NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
help.c File Reference

Generate the help-page and GUI display it. More...

#include "config.h"
#include <stddef.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "key/lib.h"
#include "menu/lib.h"
#include "pager/lib.h"
#include "hdrline.h"
#include "protos.h"
+ Include dependency graph for help.c:

Go to the source code of this file.

Functions

static const struct MenuFuncOphelp_lookup_function (int op, enum MenuType menu)
 Find a keybinding for an operation.
 
static int print_macro (FILE *fp, int maxwidth, const char **macro)
 Print a macro string to a file.
 
static int get_wrapped_width (const char *t, size_t wid)
 Wrap a string at a sensible place.
 
static int pad (FILE *fp, int col, int i)
 Write some padding to a file.
 
static void format_line (FILE *fp, int ismacro, const char *t1, const char *t2, const char *t3, int wraplen)
 Write a formatted line to a file.
 
static void dump_menu (FILE *fp, enum MenuType menu, int wraplen)
 Write all the key bindings to a file.
 
static bool is_bound (struct KeymapList *km_list, int op)
 Does a function have a keybinding?
 
static void dump_unbound (FILE *fp, const struct MenuFuncOp *funcs, struct KeymapList *km_list, struct KeymapList *aux, int wraplen)
 Write out all the operations with no key bindings.
 
static void show_flag_if_present (FILE *fp, int wraplen, const struct MbTable *table, int index, char *description)
 Write out a message flag if exists.
 
static void dump_message_flags (FILE *fp, int wraplen)
 Write out all the message flags.
 
void mutt_help (enum MenuType menu)
 Display the help menu.
 

Detailed Description

Generate the help-page and GUI display it.

Authors
  • Michael R. Elkins

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

Function Documentation

◆ help_lookup_function()

static const struct MenuFuncOp * help_lookup_function ( int  op,
enum MenuType  menu 
)
static

Find a keybinding for an operation.

Parameters
opOperation, e.g. OP_DELETE
menuCurrent Menu, e.g. MENU_PAGER
Return values
ptrKey binding
NULLNo key binding found

Definition at line 53 of file help.c.

54{
55 if (menu != MENU_PAGER && (menu != MENU_GENERIC))
56 {
57 /* first look in the generic map for the function */
58 for (int i = 0; OpGeneric[i].name; i++)
59 if (OpGeneric[i].op == op)
60 return &OpGeneric[i];
61 }
62
63 const struct MenuFuncOp *funcs = km_get_table(menu);
64 if (funcs)
65 {
66 for (int i = 0; funcs[i].name; i++)
67 if (funcs[i].op == op)
68 return &funcs[i];
69 }
70
71 return NULL;
72}
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:67
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: lib.c:532
Mapping between a function and an operation.
Definition: lib.h:102
const char * name
Name of the function.
Definition: lib.h:103
int op
Operation, e.g. OP_DELETE.
Definition: lib.h:104
@ MENU_GENERIC
Generic selection list.
Definition: type.h:46
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_macro()

static int print_macro ( FILE *  fp,
int  maxwidth,
const char **  macro 
)
static

Print a macro string to a file.

Parameters
[in]fpFile to write to
[in]maxwidthMaximum width in screen columns
[out]macroMacro string
Return values
numNumber of screen columns used

The macro pointer is move past the string we've printed

Definition at line 83 of file help.c.

84{
85 int n = maxwidth;
86 wchar_t wc = 0;
87 size_t k;
88 size_t len = mutt_str_len(*macro);
89 mbstate_t mbstate1 = { 0 };
90 mbstate_t mbstate2 = { 0 };
91
92 for (; len && (k = mbrtowc(&wc, *macro, len, &mbstate1)); *macro += k, len -= k)
93 {
94 if ((k == ICONV_ILLEGAL_SEQ) || (k == ICONV_BUF_TOO_SMALL))
95 {
96 if (k == ICONV_ILLEGAL_SEQ)
97 memset(&mbstate1, 0, sizeof(mbstate1));
98 k = (k == ICONV_ILLEGAL_SEQ) ? 1 : len;
99 wc = ReplacementChar;
100 }
101 /* glibc-2.1.3's wcwidth() returns 1 for unprintable chars! */
102 const int w = wcwidth(wc);
103 if (IsWPrint(wc) && (w >= 0))
104 {
105 if (w > n)
106 break;
107 n -= w;
108 {
109 char buf[MB_LEN_MAX * 2];
110 size_t n1, n2;
111 if (((n1 = wcrtomb(buf, wc, &mbstate2)) != ICONV_ILLEGAL_SEQ) &&
112 ((n2 = wcrtomb(buf + n1, 0, &mbstate2)) != ICONV_ILLEGAL_SEQ))
113 {
114 fputs(buf, fp);
115 }
116 }
117 }
118 else if ((wc < 0x20) || (wc == 0x7f))
119 {
120 if (n < 2)
121 break;
122 n -= 2;
123 if (wc == '\033') // Escape
124 fprintf(fp, "\\e");
125 else if (wc == '\n')
126 fprintf(fp, "\\n");
127 else if (wc == '\r')
128 fprintf(fp, "\\r");
129 else if (wc == '\t')
130 fprintf(fp, "\\t");
131 else
132 fprintf(fp, "^%c", (char) ((wc + '@') & 0x7f));
133 }
134 else
135 {
136 if (n < 1)
137 break;
138 n -= 1;
139 fprintf(fp, "?");
140 }
141 }
142 return maxwidth - n;
143}
#define IsWPrint(wc)
Definition: mbyte.h:41
wchar_t ReplacementChar
When a Unicode character can't be displayed, use this instead.
Definition: charset.c:58
#define ICONV_BUF_TOO_SMALL
Error value for iconv() - Buffer too small.
Definition: charset.h:105
#define ICONV_ILLEGAL_SEQ
Error value for iconv() - Illegal sequence.
Definition: charset.h:103
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:568
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_wrapped_width()

static int get_wrapped_width ( const char *  t,
size_t  wid 
)
static

Wrap a string at a sensible place.

Parameters
tString to wrap
widMaximum width
Return values
numBreak after this many characters

If the string's too long, look for some whitespace to break at.

Definition at line 153 of file help.c.

154{
155 wchar_t wc = 0;
156 size_t k;
157 size_t m, n;
158 size_t len = mutt_str_len(t);
159 const char *s = t;
160 mbstate_t mbstate = { 0 };
161
162 for (m = wid, n = 0; len && (k = mbrtowc(&wc, s, len, &mbstate)) && (n <= wid);
163 s += k, len -= k)
164 {
165 if (*s == ' ')
166 m = n;
167 if ((k == ICONV_ILLEGAL_SEQ) || (k == ICONV_BUF_TOO_SMALL))
168 {
169 if (k == ICONV_ILLEGAL_SEQ)
170 memset(&mbstate, 0, sizeof(mbstate));
171 k = (k == ICONV_ILLEGAL_SEQ) ? 1 : len;
172 wc = ReplacementChar;
173 }
174 if (!IsWPrint(wc))
175 wc = '?';
176 n += wcwidth(wc);
177 }
178 if (n > wid)
179 n = m;
180 else
181 n = wid;
182 return n;
183}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pad()

static int pad ( FILE *  fp,
int  col,
int  i 
)
static

Write some padding to a file.

Parameters
fpFile to write to
colCurrent screen column
iScreen column to pad until
Return values
num
  • i - Padding was added
  • col - Content was already wider than col

Definition at line 194 of file help.c.

195{
196 if (col < i)
197 {
198 char fmt[32] = { 0 };
199 snprintf(fmt, sizeof(fmt), "%%-%ds", i - col);
200 fprintf(fp, fmt, "");
201 return i;
202 }
203 fputc(' ', fp);
204 return col + 1;
205}
+ Here is the caller graph for this function:

◆ format_line()

static void format_line ( FILE *  fp,
int  ismacro,
const char *  t1,
const char *  t2,
const char *  t3,
int  wraplen 
)
static

Write a formatted line to a file.

Parameters
fpFile to write to
ismacroLayout mode, see below
t1Text part 1
t2Text part 2
t3Text part 3
wraplenWidth to wrap to

Assemble the three columns of text.

ismacro can be:

  • 1 : Macro with a description
  • 0 : Non-macro
  • -1 : Macro with no description

Definition at line 223 of file help.c.

225{
226 int col;
227 int col_b;
228
229 fputs(t1, fp);
230
231 /* don't try to press string into one line with less than 40 characters. */
232 bool split = (wraplen < 40);
233 if (split)
234 {
235 col = 0;
236 col_b = 1024;
237 fputc('\n', fp);
238 }
239 else
240 {
241 const int col_a = (wraplen > 83) ? (wraplen - 32) >> 2 : 12;
242 col_b = (wraplen > 49) ? (wraplen - 10) >> 1 : 19;
243 col = pad(fp, mutt_strwidth(t1), col_a);
244 }
245
246 const char *const c_pager = pager_get_pager(NeoMutt->sub);
247 if (ismacro > 0)
248 {
249 if (!c_pager)
250 fputs("_\010", fp); // Ctrl-H (backspace)
251 fputs("M ", fp);
252 col += 2;
253
254 if (!split)
255 {
256 col += print_macro(fp, col_b - col - 4, &t2);
257 if (mutt_strwidth(t2) > col_b - col)
258 t2 = "...";
259 }
260 }
261
262 col += print_macro(fp, col_b - col - 1, &t2);
263 if (split)
264 fputc('\n', fp);
265 else
266 col = pad(fp, col, col_b);
267
268 if (split)
269 {
270 print_macro(fp, 1024, &t3);
271 fputc('\n', fp);
272 }
273 else
274 {
275 while (*t3)
276 {
277 int n = wraplen - col;
278
279 if (ismacro >= 0)
280 {
281 SKIPWS(t3);
282 n = get_wrapped_width(t3, n);
283 }
284
285 n = print_macro(fp, n, &t3);
286
287 if (*t3)
288 {
289 if (c_pager)
290 {
291 fputc('\n', fp);
292 n = 0;
293 }
294 else
295 {
296 n += col - wraplen;
297 const bool c_markers = cs_subset_bool(NeoMutt->sub, "markers");
298 if (c_markers)
299 n++;
300 }
301 col = pad(fp, n, col_b);
302 }
303 }
304 }
305
306 fputc('\n', fp);
307}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:647
static int pad(FILE *fp, int col, int i)
Write some padding to a file.
Definition: help.c:194
static int get_wrapped_width(const char *t, size_t wid)
Wrap a string at a sensible place.
Definition: help.c:153
static int print_macro(FILE *fp, int maxwidth, const char **macro)
Print a macro string to a file.
Definition: help.c:83
const char * pager_get_pager(struct ConfigSubset *sub)
Get the value of $pager.
Definition: config.c:103
#define SKIPWS(ch)
Definition: string2.h:45
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_menu()

static void dump_menu ( FILE *  fp,
enum MenuType  menu,
int  wraplen 
)
static

Write all the key bindings to a file.

Parameters
fpFile to write to
menuCurrent Menu, e.g. MENU_PAGER
wraplenWidth to wrap to

Definition at line 315 of file help.c.

316{
317 struct Keymap *map = NULL;
318 char buf[128] = { 0 };
319
320 STAILQ_FOREACH(map, &Keymaps[menu], entries)
321 {
322 if (map->op != OP_NULL)
323 {
324 km_expand_key(buf, sizeof(buf), map);
325
326 if (map->op == OP_MACRO)
327 {
328 if (map->desc)
329 format_line(fp, 1, buf, map->macro, map->desc, wraplen);
330 else
331 format_line(fp, -1, buf, "macro", map->macro, wraplen);
332 }
333 else
334 {
335 const struct MenuFuncOp *funcs = help_lookup_function(map->op, menu);
336 format_line(fp, 0, buf, funcs ? funcs->name : "UNKNOWN",
337 funcs ? _(opcodes_get_description(funcs->op)) :
338 _("ERROR: please report this bug"),
339 wraplen);
340 }
341 }
342 }
343}
static void format_line(FILE *fp, int ismacro, const char *t1, const char *t2, const char *t3, int wraplen)
Write a formatted line to a file.
Definition: help.c:223
static const struct MenuFuncOp * help_lookup_function(int op, enum MenuType menu)
Find a keybinding for an operation.
Definition: help.c:53
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition: lib.c:129
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: lib.c:464
#define _(a)
Definition: message.h:28
const char * opcodes_get_description(int op)
Get the description of an opcode.
Definition: opcodes.c:70
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_bound()

static bool is_bound ( struct KeymapList *  km_list,
int  op 
)
static

Does a function have a keybinding?

Parameters
km_listKeymap to examine
opOperation, e.g. OP_DELETE
Return values
trueA key is bound to that operation

Definition at line 351 of file help.c.

352{
353 struct Keymap *map = NULL;
354 STAILQ_FOREACH(map, km_list, entries)
355 {
356 if (map->op == op)
357 return true;
358 }
359 return false;
360}
+ Here is the caller graph for this function:

◆ dump_unbound()

static void dump_unbound ( FILE *  fp,
const struct MenuFuncOp funcs,
struct KeymapList *  km_list,
struct KeymapList *  aux,
int  wraplen 
)
static

Write out all the operations with no key bindings.

Parameters
fpFile to write to
funcsAll the bindings for the current menu
km_listFirst key map to consider
auxSecond key map to consider
wraplenWidth to wrap to

Definition at line 370 of file help.c.

372{
373 for (int i = 0; funcs[i].name; i++)
374 {
375 if (!is_bound(km_list, funcs[i].op) && (!aux || !is_bound(aux, funcs[i].op)))
376 format_line(fp, 0, funcs[i].name, "", _(opcodes_get_description(funcs[i].op)), wraplen);
377 }
378}
static bool is_bound(struct KeymapList *km_list, int op)
Does a function have a keybinding?
Definition: help.c:351
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ show_flag_if_present()

static void show_flag_if_present ( FILE *  fp,
int  wraplen,
const struct MbTable table,
int  index,
char *  description 
)
static

Write out a message flag if exists.

Parameters
fpFile to write to
wraplenWidth to wrap to
tableTable containing the flag characters
indexIndex of flag character int the table
descriptionDescription of flag

Definition at line 388 of file help.c.

390{
391 const char *flag = mbtable_get_nth_wchar(table, index);
392 if ((strlen(flag) < 1) || (*flag == ' '))
393 {
394 return;
395 }
396
397 format_line(fp, 0, flag, "", description, wraplen);
398}
const char * mbtable_get_nth_wchar(const struct MbTable *table, int index)
Extract one char from a multi-byte table.
Definition: mbtable.c:302
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_message_flags()

static void dump_message_flags ( FILE *  fp,
int  wraplen 
)
static

Write out all the message flags.

Parameters
fpFile to write to
wraplenWidth to wrap to

Definition at line 405 of file help.c.

406{
407 const struct MbTable *c_flag_chars = cs_subset_mbtable(NeoMutt->sub, "flag_chars");
408 const struct MbTable *c_crypt_chars = cs_subset_mbtable(NeoMutt->sub, "crypt_chars");
409 const struct MbTable *c_to_chars = cs_subset_mbtable(NeoMutt->sub, "to_chars");
410
411 format_line(fp, 0, "$flag_chars:", "", "", wraplen);
412 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_TAGGED, _("message is tagged"));
413 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_IMPORTANT,
414 _("message is flagged"));
415 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_DELETED, _("message is deleted"));
416 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_DELETED_ATTACH,
417 _("attachment is deleted"));
418 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_REPLIED,
419 _("message has been replied to"));
420 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_OLD, _("message has been read"));
421 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_NEW, _("message is new"));
422 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_OLD_THREAD,
423 _("thread has been read"));
424 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_NEW_THREAD,
425 _("thread has at least one new message"));
426 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_SEMPTY,
427 _("message has been read (%S expando)"));
428 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_ZEMPTY,
429 _("message has been read (%Z expando)"));
430
431 format_line(fp, 0, "\n$crypt_chars:", "", "", wraplen);
432 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_GOOD_SIGN,
433 _("message signed with a verified key"));
434 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_ENCRYPTED,
435 _("message is PGP-encrypted"));
436 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_SIGNED,
437 _("message is signed"));
438 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_CONTAINS_KEY,
439 _("message contains a PGP key"));
440 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_NO_CRYPTO,
441 _("message has no cryptography information"));
442
443 format_line(fp, 0, "\n$to_chars:", "", "", wraplen);
444 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_NOT_IN_THE_LIST,
445 _("message is not To: you"));
446 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_UNIQUE,
447 _("message is To: you and only you"));
448 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_TO, _("message is To: you"));
449 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_CC, _("message is Cc: to you"));
450 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_ORIGINATOR,
451 _("message is From: you"));
452 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_SUBSCRIBED_LIST,
453 _("message is sent to a subscribed mailing list"));
454 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_REPLY_TO,
455 _("you are in the Reply-To: list"));
456}
struct MbTable * cs_subset_mbtable(const struct ConfigSubset *sub, const char *name)
Get a Multibyte table config item by name.
Definition: helpers.c:120
@ FLAG_CHAR_TO_ORIGINATOR
Character denoting that the user is originator.
Definition: hdrline.h:72
@ FLAG_CHAR_TO_UNIQUE
Character denoting that the user is unique recipient.
Definition: hdrline.h:69
@ FLAG_CHAR_TO_NOT_IN_THE_LIST
Character denoting that the user is not in list.
Definition: hdrline.h:68
@ FLAG_CHAR_TO_TO
Character denoting that the user is in the TO list.
Definition: hdrline.h:70
@ FLAG_CHAR_TO_CC
Character denoting that the user is in the CC list.
Definition: hdrline.h:71
@ FLAG_CHAR_TO_REPLY_TO
Character denoting that the user is in the Reply-To list.
Definition: hdrline.h:74
@ FLAG_CHAR_TO_SUBSCRIBED_LIST
Character denoting that the message is sent to a subscribed mailing list.
Definition: hdrline.h:73
@ FLAG_CHAR_CRYPT_CONTAINS_KEY
Character denoting a message contains a PGP key.
Definition: hdrline.h:59
@ FLAG_CHAR_CRYPT_SIGNED
Character denoting a message is signed.
Definition: hdrline.h:58
@ FLAG_CHAR_CRYPT_NO_CRYPTO
Character denoting a message has no cryptography information.
Definition: hdrline.h:60
@ FLAG_CHAR_CRYPT_GOOD_SIGN
Character denoting a message signed with a verified key.
Definition: hdrline.h:56
@ FLAG_CHAR_CRYPT_ENCRYPTED
Character denoting a message is PGP-encrypted.
Definition: hdrline.h:57
@ FLAG_CHAR_OLD
Character denoting an email that has been read.
Definition: hdrline.h:43
@ FLAG_CHAR_REPLIED
Character denoting an email that has been replied to.
Definition: hdrline.h:42
@ FLAG_CHAR_OLD_THREAD
Character denoting a thread of emails that has been read.
Definition: hdrline.h:45
@ FLAG_CHAR_ZEMPTY
Character denoting a read email, $index_format Z expando.
Definition: hdrline.h:48
@ FLAG_CHAR_TAGGED
Character denoting a tagged email.
Definition: hdrline.h:38
@ FLAG_CHAR_NEW
Character denoting an unread email.
Definition: hdrline.h:44
@ FLAG_CHAR_DELETED
Character denoting a deleted email.
Definition: hdrline.h:40
@ FLAG_CHAR_NEW_THREAD
Character denoting a thread containing at least one new email.
Definition: hdrline.h:46
@ FLAG_CHAR_DELETED_ATTACH
Character denoting a deleted attachment.
Definition: hdrline.h:41
@ FLAG_CHAR_SEMPTY
Character denoting a read email, $index_format S expando.
Definition: hdrline.h:47
@ FLAG_CHAR_IMPORTANT
Character denoting a important (flagged) email.
Definition: hdrline.h:39
static void show_flag_if_present(FILE *fp, int wraplen, const struct MbTable *table, int index, char *description)
Write out a message flag if exists.
Definition: help.c:388
Multibyte character table.
Definition: mbtable.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_help()

void mutt_help ( enum MenuType  menu)

Display the help menu.

Parameters
menuCurrent Menu

Definition at line 462 of file help.c.

463{
464 char banner[128] = { 0 };
465 FILE *fp = NULL;
466
467 /* We don't use the buffer pool because of the extended lifetime of t */
468 struct Buffer t = buf_make(PATH_MAX);
469 buf_mktemp(&t);
470
471 const struct MenuFuncOp *funcs = km_get_table(menu);
472 const char *desc = mutt_map_get_name(menu, MenuNames);
473 if (!desc)
474 desc = _("<UNKNOWN>");
475
476 struct PagerData pdata = { 0 };
477 struct PagerView pview = { &pdata };
478
479 pview.mode = PAGER_MODE_HELP;
482
483 do
484 {
485 fp = mutt_file_fopen(buf_string(&t), "w");
486 if (!fp)
487 {
488 mutt_perror("%s", buf_string(&t));
489 goto cleanup;
490 }
491
492 const int wraplen = AllDialogsWindow->state.cols;
493 dump_menu(fp, menu, wraplen);
494 if ((menu != MENU_EDITOR) && (menu != MENU_PAGER) && (menu != MENU_GENERIC))
495 {
496 fprintf(fp, "\n%s\n\n", _("Generic bindings:"));
497 dump_menu(fp, MENU_GENERIC, wraplen);
498 }
499
500 fprintf(fp, "\n%s\n\n", _("Unbound functions:"));
501 if (funcs)
502 dump_unbound(fp, funcs, &Keymaps[menu], NULL, wraplen);
503 if ((menu != MENU_EDITOR) && (menu != MENU_PAGER) && (menu != MENU_GENERIC))
504 dump_unbound(fp, OpGeneric, &Keymaps[MENU_GENERIC], &Keymaps[menu], wraplen);
505
506 if (menu == MENU_INDEX)
507 {
508 fprintf(fp, "\n%s\n\n", _("Message flags:"));
509 dump_message_flags(fp, wraplen);
510 }
511
512 mutt_file_fclose(&fp);
513
514 snprintf(banner, sizeof(banner), _("Help for %s"), desc);
515 pdata.fname = buf_string(&t);
516 pview.banner = banner;
517 } while (mutt_do_pager(&pview, NULL) == OP_REFORMAT_WINCH);
518
519cleanup:
520 buf_dealloc(&t);
521}
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:389
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:70
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
struct MuttWindow * AllDialogsWindow
Parent of all Dialogs.
Definition: dialog.c:80
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:636
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
#define mutt_perror(...)
Definition: logging2.h:93
static void dump_unbound(FILE *fp, const struct MenuFuncOp *funcs, struct KeymapList *km_list, struct KeymapList *aux, int wraplen)
Write out all the operations with no key bindings.
Definition: help.c:370
static void dump_message_flags(FILE *fp, int wraplen)
Write out all the message flags.
Definition: help.c:405
static void dump_menu(FILE *fp, enum MenuType menu, int wraplen)
Write all the key bindings to a file.
Definition: help.c:315
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
#define PATH_MAX
Definition: mutt.h:41
#define MUTT_PAGER_RETWINCH
Need reformatting on SIGWINCH.
Definition: lib.h:70
#define MUTT_PAGER_NSKIP
Preserve whitespace with smartwrap.
Definition: lib.h:68
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:72
#define MUTT_PAGER_STRIPES
Striped highlighting.
Definition: lib.h:75
#define MUTT_PAGER_MARKER
Use markers if option is set.
Definition: lib.h:69
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition: lib.h:140
String manipulation buffer.
Definition: buffer.h:34
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
Data to be displayed by PagerView.
Definition: lib.h:160
const char * fname
Name of the file to read.
Definition: lib.h:164
Paged view into some data.
Definition: lib.h:171
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:172
enum PagerMode mode
Pager mode.
Definition: lib.h:173
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:174
const char * banner
Title to display in status bar.
Definition: lib.h:175
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
#define buf_mktemp(buf)
Definition: tmp.h:33
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:37
@ MENU_INDEX
Index panel (list of emails)
Definition: type.h:51
@ MENU_EDITOR
Text entry area.
Definition: type.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function: