NeoMutt  2024-02-01-35-geee02f
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
  • Richard Russon
  • Pietro Cerutti
  • Yousef Akbar
  • Ihor Antonov
  • Tóth János

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 58 of file help.c.

59{
60 if (menu != MENU_PAGER && (menu != MENU_GENERIC))
61 {
62 /* first look in the generic map for the function */
63 for (int i = 0; OpGeneric[i].name; i++)
64 if (OpGeneric[i].op == op)
65 return &OpGeneric[i];
66 }
67
68 const struct MenuFuncOp *funcs = km_get_table(menu);
69 if (funcs)
70 {
71 for (int i = 0; funcs[i].name; i++)
72 if (funcs[i].op == op)
73 return &funcs[i];
74 }
75
76 return NULL;
77}
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:68
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: lib.c:528
Mapping between a function and an operation.
Definition: lib.h:101
const char * name
Name of the function.
Definition: lib.h:102
int op
Operation, e.g. OP_DELETE.
Definition: lib.h:103
@ 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 88 of file help.c.

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

159{
160 wchar_t wc = 0;
161 size_t k;
162 size_t m, n;
163 size_t len = mutt_str_len(t);
164 const char *s = t;
165 mbstate_t mbstate = { 0 };
166
167 for (m = wid, n = 0; len && (k = mbrtowc(&wc, s, len, &mbstate)) && (n <= wid);
168 s += k, len -= k)
169 {
170 if (*s == ' ')
171 m = n;
172 if ((k == ICONV_ILLEGAL_SEQ) || (k == ICONV_BUF_TOO_SMALL))
173 {
174 if (k == ICONV_ILLEGAL_SEQ)
175 memset(&mbstate, 0, sizeof(mbstate));
176 k = (k == ICONV_ILLEGAL_SEQ) ? 1 : len;
177 wc = ReplacementChar;
178 }
179 if (!IsWPrint(wc))
180 wc = '?';
181 n += wcwidth(wc);
182 }
183 if (n > wid)
184 n = m;
185 else
186 n = wid;
187 return n;
188}
+ 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 199 of file help.c.

200{
201 if (col < i)
202 {
203 char fmt[32] = { 0 };
204 snprintf(fmt, sizeof(fmt), "%%-%ds", i - col);
205 fprintf(fp, fmt, "");
206 return i;
207 }
208 fputc(' ', fp);
209 return col + 1;
210}
+ 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 228 of file help.c.

230{
231 int col;
232 int col_b;
233
234 fputs(t1, fp);
235
236 /* don't try to press string into one line with less than 40 characters. */
237 bool split = (wraplen < 40);
238 if (split)
239 {
240 col = 0;
241 col_b = 1024;
242 fputc('\n', fp);
243 }
244 else
245 {
246 const int col_a = (wraplen > 83) ? (wraplen - 32) >> 2 : 12;
247 col_b = (wraplen > 49) ? (wraplen - 10) >> 1 : 19;
248 col = pad(fp, mutt_strwidth(t1), col_a);
249 }
250
251 const char *const c_pager = pager_get_pager(NeoMutt->sub);
252 if (ismacro > 0)
253 {
254 if (!c_pager)
255 fputs("_\010", fp); // Ctrl-H (backspace)
256 fputs("M ", fp);
257 col += 2;
258
259 if (!split)
260 {
261 col += print_macro(fp, col_b - col - 4, &t2);
262 if (mutt_strwidth(t2) > col_b - col)
263 t2 = "...";
264 }
265 }
266
267 col += print_macro(fp, col_b - col - 1, &t2);
268 if (split)
269 fputc('\n', fp);
270 else
271 col = pad(fp, col, col_b);
272
273 if (split)
274 {
275 print_macro(fp, 1024, &t3);
276 fputc('\n', fp);
277 }
278 else
279 {
280 while (*t3)
281 {
282 int n = wraplen - col;
283
284 if (ismacro >= 0)
285 {
286 SKIPWS(t3);
287 n = get_wrapped_width(t3, n);
288 }
289
290 n = print_macro(fp, n, &t3);
291
292 if (*t3)
293 {
294 if (c_pager)
295 {
296 fputc('\n', fp);
297 n = 0;
298 }
299 else
300 {
301 n += col - wraplen;
302 const bool c_markers = cs_subset_bool(NeoMutt->sub, "markers");
303 if (c_markers)
304 n++;
305 }
306 col = pad(fp, n, col_b);
307 }
308 }
309 }
310
311 fputc('\n', fp);
312}
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:445
static int pad(FILE *fp, int col, int i)
Write some padding to a file.
Definition: help.c:199
static int get_wrapped_width(const char *t, size_t wid)
Wrap a string at a sensible place.
Definition: help.c:158
static int print_macro(FILE *fp, int maxwidth, const char **macro)
Print a macro string to a file.
Definition: help.c:88
const char * pager_get_pager(struct ConfigSubset *sub)
Get the value of $pager.
Definition: config.c:105
#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 320 of file help.c.

321{
322 struct Keymap *map = NULL;
323 char buf[128] = { 0 };
324
325 STAILQ_FOREACH(map, &Keymaps[menu], entries)
326 {
327 if (map->op != OP_NULL)
328 {
329 km_expand_key(buf, sizeof(buf), map);
330
331 if (map->op == OP_MACRO)
332 {
333 if (map->desc)
334 format_line(fp, 1, buf, map->macro, map->desc, wraplen);
335 else
336 format_line(fp, -1, buf, "macro", map->macro, wraplen);
337 }
338 else
339 {
340 const struct MenuFuncOp *funcs = help_lookup_function(map->op, menu);
341 format_line(fp, 0, buf, funcs ? funcs->name : "UNKNOWN",
342 funcs ? _(opcodes_get_description(funcs->op)) :
343 _("ERROR: please report this bug"),
344 wraplen);
345 }
346 }
347 }
348}
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:228
static const struct MenuFuncOp * help_lookup_function(int op, enum MenuType menu)
Find a keybinding for an operation.
Definition: help.c:58
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition: lib.c:128
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: lib.c:460
#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:65
char * macro
Macro expansion (op == OP_MACRO)
Definition: lib.h:66
char * desc
Description of a macro for the help menu.
Definition: lib.h:67
short op
Operation to perform.
Definition: lib.h:68
+ 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 356 of file help.c.

357{
358 struct Keymap *map = NULL;
359 STAILQ_FOREACH(map, km_list, entries)
360 {
361 if (map->op == op)
362 return true;
363 }
364 return false;
365}
+ 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 375 of file help.c.

377{
378 for (int i = 0; funcs[i].name; i++)
379 {
380 if (!is_bound(km_list, funcs[i].op) && (!aux || !is_bound(aux, funcs[i].op)))
381 format_line(fp, 0, funcs[i].name, "", _(opcodes_get_description(funcs[i].op)), wraplen);
382 }
383}
static bool is_bound(struct KeymapList *km_list, int op)
Does a function have a keybinding?
Definition: help.c:356
+ 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 393 of file help.c.

395{
396 const char *flag = mbtable_get_nth_wchar(table, index);
397 if ((strlen(flag) < 1) || (*flag == ' '))
398 {
399 return;
400 }
401
402 format_line(fp, 0, flag, "", description, wraplen);
403}
const char * mbtable_get_nth_wchar(const struct MbTable *table, int index)
Extract one char from a multi-byte table.
Definition: mbtable.c:331
+ 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 410 of file help.c.

411{
412 const struct MbTable *c_flag_chars = cs_subset_mbtable(NeoMutt->sub, "flag_chars");
413 const struct MbTable *c_crypt_chars = cs_subset_mbtable(NeoMutt->sub, "crypt_chars");
414 const struct MbTable *c_to_chars = cs_subset_mbtable(NeoMutt->sub, "to_chars");
415
416 format_line(fp, 0, "$flag_chars:", "", "", wraplen);
417 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_TAGGED, _("message is tagged"));
418 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_IMPORTANT,
419 _("message is flagged"));
420 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_DELETED, _("message is deleted"));
421 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_DELETED_ATTACH,
422 _("attachment is deleted"));
423 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_REPLIED,
424 _("message has been replied to"));
425 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_OLD, _("message has been read"));
426 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_NEW, _("message is new"));
427 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_OLD_THREAD,
428 _("thread has been read"));
429 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_NEW_THREAD,
430 _("thread has at least one new message"));
431 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_SEMPTY,
432 _("message has been read (%S expando)"));
433 show_flag_if_present(fp, wraplen, c_flag_chars, FLAG_CHAR_ZEMPTY,
434 _("message has been read (%Z expando)"));
435
436 format_line(fp, 0, "\n$crypt_chars:", "", "", wraplen);
437 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_GOOD_SIGN,
438 _("message signed with a verified key"));
439 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_ENCRYPTED,
440 _("message is PGP-encrypted"));
441 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_SIGNED,
442 _("message is signed"));
443 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_CONTAINS_KEY,
444 _("message contains a PGP key"));
445 show_flag_if_present(fp, wraplen, c_crypt_chars, FLAG_CHAR_CRYPT_NO_CRYPTO,
446 _("message has no cryptography information"));
447
448 format_line(fp, 0, "\n$to_chars:", "", "", wraplen);
449 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_NOT_IN_THE_LIST,
450 _("message is not To: you"));
451 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_UNIQUE,
452 _("message is To: you and only you"));
453 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_TO, _("message is To: you"));
454 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_CC, _("message is Cc: to you"));
455 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_ORIGINATOR,
456 _("message is From: you"));
457 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_SUBSCRIBED_LIST,
458 _("message is sent to a subscribed mailing list"));
459 show_flag_if_present(fp, wraplen, c_to_chars, FLAG_CHAR_TO_REPLY_TO,
460 _("you are in the Reply-To: list"));
461}
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:73
@ FLAG_CHAR_TO_UNIQUE
Character denoting that the user is unique recipient.
Definition: hdrline.h:70
@ FLAG_CHAR_TO_NOT_IN_THE_LIST
Character denoting that the user is not in list.
Definition: hdrline.h:69
@ FLAG_CHAR_TO_TO
Character denoting that the user is in the TO list.
Definition: hdrline.h:71
@ FLAG_CHAR_TO_CC
Character denoting that the user is in the CC list.
Definition: hdrline.h:72
@ FLAG_CHAR_TO_REPLY_TO
Character denoting that the user is in the Reply-To list.
Definition: hdrline.h:75
@ FLAG_CHAR_TO_SUBSCRIBED_LIST
Character denoting that the message is sent to a subscribed mailing list.
Definition: hdrline.h:74
@ FLAG_CHAR_CRYPT_CONTAINS_KEY
Character denoting a message contains a PGP key.
Definition: hdrline.h:60
@ FLAG_CHAR_CRYPT_SIGNED
Character denoting a message is signed.
Definition: hdrline.h:59
@ FLAG_CHAR_CRYPT_NO_CRYPTO
Character denoting a message has no cryptography information.
Definition: hdrline.h:61
@ FLAG_CHAR_CRYPT_GOOD_SIGN
Character denoting a message signed with a verified key.
Definition: hdrline.h:57
@ FLAG_CHAR_CRYPT_ENCRYPTED
Character denoting a message is PGP-encrypted.
Definition: hdrline.h:58
@ FLAG_CHAR_OLD
Character denoting an email that has been read.
Definition: hdrline.h:44
@ FLAG_CHAR_REPLIED
Character denoting an email that has been replied to.
Definition: hdrline.h:43
@ FLAG_CHAR_OLD_THREAD
Character denoting a thread of emails that has been read.
Definition: hdrline.h:46
@ FLAG_CHAR_ZEMPTY
Character denoting a read email, $index_format Z expando.
Definition: hdrline.h:49
@ FLAG_CHAR_TAGGED
Character denoting a tagged email.
Definition: hdrline.h:39
@ FLAG_CHAR_NEW
Character denoting an unread email.
Definition: hdrline.h:45
@ FLAG_CHAR_DELETED
Character denoting a deleted email.
Definition: hdrline.h:41
@ FLAG_CHAR_NEW_THREAD
Character denoting a thread containing at least one new email.
Definition: hdrline.h:47
@ FLAG_CHAR_DELETED_ATTACH
Character denoting a deleted attachment.
Definition: hdrline.h:42
@ FLAG_CHAR_SEMPTY
Character denoting a read email, $index_format S expando.
Definition: hdrline.h:48
@ FLAG_CHAR_IMPORTANT
Character denoting a important (flagged) email.
Definition: hdrline.h:40
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:393
Multibyte character table.
Definition: mbtable.h:36
+ 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 467 of file help.c.

468{
469 char banner[128] = { 0 };
470 FILE *fp = NULL;
471
472 /* We don't use the buffer pool because of the extended lifetime of t */
473 struct Buffer t = buf_make(PATH_MAX);
474 buf_mktemp(&t);
475
476 const struct MenuFuncOp *funcs = km_get_table(menu);
477 const char *desc = mutt_map_get_name(menu, MenuNames);
478 if (!desc)
479 desc = _("<UNKNOWN>");
480
481 struct PagerData pdata = { 0 };
482 struct PagerView pview = { &pdata };
483
484 pview.mode = PAGER_MODE_HELP;
487
488 do
489 {
490 fp = mutt_file_fopen(buf_string(&t), "w");
491 if (!fp)
492 {
493 mutt_perror("%s", buf_string(&t));
494 goto cleanup;
495 }
496
497 const int wraplen = AllDialogsWindow->state.cols;
498 dump_menu(fp, menu, wraplen);
499 if ((menu != MENU_EDITOR) && (menu != MENU_PAGER) && (menu != MENU_GENERIC))
500 {
501 fprintf(fp, "\n%s\n\n", _("Generic bindings:"));
502 dump_menu(fp, MENU_GENERIC, wraplen);
503 }
504
505 fprintf(fp, "\n%s\n\n", _("Unbound functions:"));
506 if (funcs)
507 dump_unbound(fp, funcs, &Keymaps[menu], NULL, wraplen);
508 if ((menu != MENU_EDITOR) && (menu != MENU_PAGER) && (menu != MENU_GENERIC))
509 dump_unbound(fp, OpGeneric, &Keymaps[MENU_GENERIC], &Keymaps[menu], wraplen);
510
511 if (menu == MENU_INDEX)
512 {
513 fprintf(fp, "\n%s\n\n", _("Message flags:"));
514 dump_message_flags(fp, wraplen);
515 }
516
517 mutt_file_fclose(&fp);
518
519 snprintf(banner, sizeof(banner), _("Help for %s"), desc);
520 pdata.fname = buf_string(&t);
521 pview.banner = banner;
522 } while (mutt_do_pager(&pview, NULL) == OP_REFORMAT_WINCH);
523
524cleanup:
525 buf_dealloc(&t);
526}
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:394
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:75
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:97
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
#define mutt_file_fclose(FP)
Definition: file.h:148
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:147
#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:375
static void dump_message_flags(FILE *fp, int wraplen)
Write out all the message flags.
Definition: help.c:410
static void dump_menu(FILE *fp, enum MenuType menu, int wraplen)
Write all the key bindings to a file.
Definition: help.c:320
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:42
#define MUTT_PAGER_RETWINCH
Need reformatting on SIGWINCH.
Definition: lib.h:71
#define MUTT_PAGER_NSKIP
Preserve whitespace with smartwrap.
Definition: lib.h:69
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:73
#define MUTT_PAGER_STRIPES
Striped highlighting.
Definition: lib.h:76
#define MUTT_PAGER_MARKER
Use markers if option is set.
Definition: lib.h:70
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition: lib.h:141
String manipulation buffer.
Definition: buffer.h:36
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
Data to be displayed by PagerView.
Definition: lib.h:161
const char * fname
Name of the file to read.
Definition: lib.h:165
Paged view into some data.
Definition: lib.h:172
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:173
enum PagerMode mode
Pager mode.
Definition: lib.h:174
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:175
const char * banner
Title to display in status bar.
Definition: lib.h:176
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: