NeoMutt  2025-01-09-117-gace867
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
help.c
Go to the documentation of this file.
1
34#include "config.h"
35#include <stdbool.h>
36#include <stddef.h>
37#include <stdio.h>
38#include "mutt/lib.h"
39#include "config/lib.h"
40#include "core/lib.h"
41#include "gui/lib.h"
42#include "index/lib.h"
43#include "key/lib.h"
44#include "menu/lib.h"
45#include "pager/lib.h"
46#include "protos.h"
47
53static const char *FlagCharsDesc[] = {
54 N_("message is tagged"),
55 N_("message is flagged"),
56 N_("message is deleted"),
57 N_("attachment is deleted"),
58 N_("message has been replied to"),
59 N_("message has been read"),
60 N_("message is new"),
61 N_("thread has been read"),
62 N_("thread has at least one new message"),
63 N_("message has been read (%S expando)"),
64 N_("message has been read (%Z expando)"),
65};
66
72static const char *CryptCharsDesc[] = {
73 N_("message signed with a verified key"),
74 N_("message is PGP-encrypted"),
75 N_("message is signed"),
76 N_("message contains a PGP key"),
77 N_("message has no cryptography information"),
78};
79
85static const char *ToCharsDesc[] = {
86 N_("message is not To: you"),
87 N_("message is To: you and only you"),
88 N_("message is To: you"),
89 N_("message is Cc: to you"),
90 N_("message is From: you"),
91 N_("message is sent to a subscribed mailing list"),
92 N_("you are in the Reply-To: list"),
93};
94
105static void dump_message_flags(enum MenuType menu, FILE *fp)
106{
107 if (menu != MENU_INDEX)
108 return;
109
110 const char *flag = NULL;
111 int cols;
112
113 fprintf(fp, "\n%s\n\n", _("Message flags:"));
114
115 const struct MbTable *c_flag_chars = cs_subset_mbtable(NeoMutt->sub, "flag_chars");
116 fprintf(fp, "$flag_chars:\n");
117 for (int i = FLAG_CHAR_TAGGED; i <= FLAG_CHAR_ZEMPTY; i++)
118 {
119 flag = mbtable_get_nth_wchar(c_flag_chars, i);
120 cols = mutt_strwidth(flag);
121 fprintf(fp, " '%s'%*s %s\n", flag, 4 - cols, "", _(FlagCharsDesc[i]));
122 }
123
124 const struct MbTable *c_crypt_chars = cs_subset_mbtable(NeoMutt->sub, "crypt_chars");
125 fprintf(fp, "\n$crypt_chars:\n");
127 {
128 flag = mbtable_get_nth_wchar(c_crypt_chars, i);
129 cols = mutt_strwidth(flag);
130 fprintf(fp, " '%s'%*s %s\n", flag, 4 - cols, "", _(CryptCharsDesc[i]));
131 }
132
133 const struct MbTable *c_to_chars = cs_subset_mbtable(NeoMutt->sub, "to_chars");
134 fprintf(fp, "\n$to_chars:\n");
136 {
137 flag = mbtable_get_nth_wchar(c_to_chars, i);
138 cols = mutt_strwidth(flag);
139 fprintf(fp, " '%s'%*s %s\n", flag, 4 - cols, "", _(ToCharsDesc[i]));
140 }
141
142 fprintf(fp, "\n");
143}
144
149void mutt_help(enum MenuType menu)
150{
151 struct BindingInfoArray bia_bind = ARRAY_HEAD_INITIALIZER;
152 struct BindingInfoArray bia_macro = ARRAY_HEAD_INITIALIZER;
153 struct BindingInfoArray bia_gen = ARRAY_HEAD_INITIALIZER;
154 struct BindingInfoArray bia_unbound = ARRAY_HEAD_INITIALIZER;
155 struct Buffer *banner = NULL;
156 struct Buffer *tempfile = NULL;
157
158 // ---------------------------------------------------------------------------
159 // Gather the data
160
161 gather_menu(menu, &bia_bind, &bia_macro);
162
163 ARRAY_SORT(&bia_bind, binding_sort, NULL);
164 ARRAY_SORT(&bia_macro, binding_sort, NULL);
165
166 int wb0 = measure_column(&bia_bind, 0);
167 int wb1 = measure_column(&bia_bind, 1);
168
169 const bool need_generic = (menu != MENU_EDITOR) && (menu != MENU_PAGER) &&
170 (menu != MENU_GENERIC);
171 if (need_generic)
172 {
173 gather_menu(MENU_GENERIC, &bia_gen, &bia_macro);
174
175 ARRAY_SORT(&bia_gen, binding_sort, NULL);
176 wb0 = MAX(wb0, measure_column(&bia_gen, 0));
177 wb1 = MAX(wb1, measure_column(&bia_gen, 1));
178 }
179
180 const int wm0 = measure_column(&bia_macro, 0);
181
182 const struct MenuFuncOp *funcs = km_get_table(menu);
183 gather_unbound(funcs, &Keymaps[menu], NULL, &bia_unbound);
184
185 if (need_generic)
186 gather_unbound(OpGeneric, &Keymaps[MENU_GENERIC], &Keymaps[menu], &bia_unbound);
187
188 ARRAY_SORT(&bia_unbound, binding_sort, NULL);
189 const int wu1 = measure_column(&bia_unbound, 1);
190
191 // ---------------------------------------------------------------------------
192 // Save the data to a file
193
194 tempfile = buf_pool_get();
195 buf_mktemp(tempfile);
196 FILE *fp = mutt_file_fopen(buf_string(tempfile), "w");
197 if (!fp)
198 {
199 mutt_perror("%s", buf_string(tempfile));
200 goto cleanup;
201 }
202
203 const char *menu_name = mutt_map_get_name(menu, MenuNames);
204 struct BindingInfo *bi = NULL;
205
206 fprintf(fp, "%s bindings\n", menu_name);
207 fprintf(fp, "\n");
208 ARRAY_FOREACH(bi, &bia_bind)
209 {
210 // key text description
211 fprintf(fp, "%*s %*s %s\n", -wb0, bi->a[0], -wb1, bi->a[1], bi->a[2]);
212 }
213 fprintf(fp, "\n");
214
215 if (need_generic)
216 {
217 fprintf(fp, "%s bindings\n", "generic");
218 fprintf(fp, "\n");
219 ARRAY_FOREACH(bi, &bia_gen)
220 {
221 // key function description
222 fprintf(fp, "%*s %*s %s\n", -wb0, bi->a[0], -wb1, bi->a[1], bi->a[2]);
223 }
224 fprintf(fp, "\n");
225 }
226
227 fprintf(fp, "macros\n");
228 fprintf(fp, "\n");
229 ARRAY_FOREACH(bi, &bia_macro)
230 {
231 if (bi->a[2]) // description
232 {
233 // key description, macro-text, blank line
234 fprintf(fp, "%*s %s\n", -wm0, bi->a[0], bi->a[2]);
235 fprintf(fp, "%s\n", bi->a[1]);
236 fprintf(fp, "\n");
237 }
238 else
239 {
240 // key macro-text
241 fprintf(fp, "%*s %s\n", -wm0, bi->a[0], bi->a[1]);
242 }
243 }
244 fprintf(fp, "\n");
245
246 fprintf(fp, "unbound functions\n");
247 fprintf(fp, "\n");
248 ARRAY_FOREACH(bi, &bia_unbound)
249 {
250 // function description
251 fprintf(fp, "%*s %s\n", -wu1, bi->a[1], bi->a[2]);
252 }
253
254 dump_message_flags(menu, fp);
255 mutt_file_fclose(&fp);
256
257 // ---------------------------------------------------------------------------
258 // Display data
259
260 struct PagerData pdata = { 0 };
261 struct PagerView pview = { &pdata };
262
263 pview.mode = PAGER_MODE_HELP;
265
267 buf_printf(banner, _("Help for %s"), menu_name);
268 pdata.fname = buf_string(tempfile);
269 pview.banner = buf_string(banner);
270 mutt_do_pager(&pview, NULL);
271
272cleanup:
273
275 buf_pool_release(&tempfile);
276 ARRAY_FREE(&bia_bind);
277 ARRAY_FREE(&bia_macro);
278 ARRAY_FREE(&bia_gen);
279 ARRAY_FREE(&bia_unbound);
280}
#define ARRAY_SORT(head, fn, sdata)
Sort an array.
Definition: array.h:335
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:214
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:204
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:58
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
struct MbTable * cs_subset_mbtable(const struct ConfigSubset *sub, const char *name)
Get a Multibyte table config item by name.
Definition: helpers.c:119
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:445
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:122
@ FLAG_CHAR_TO_NOT_IN_THE_LIST
Character denoting that the user is not in list.
Definition: expando_index.h:67
@ FLAG_CHAR_TO_REPLY_TO
Character denoting that the user is in the Reply-To list.
Definition: expando_index.h:73
@ FLAG_CHAR_CRYPT_NO_CRYPTO
Character denoting a message has no cryptography information.
Definition: expando_index.h:59
@ FLAG_CHAR_CRYPT_GOOD_SIGN
Character denoting a message signed with a verified key.
Definition: expando_index.h:55
@ FLAG_CHAR_ZEMPTY
Character denoting a read email, $index_format Z expando.
Definition: expando_index.h:47
@ FLAG_CHAR_TAGGED
Character denoting a tagged email.
Definition: expando_index.h:37
#define mutt_file_fclose(FP)
Definition: file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:138
#define mutt_perror(...)
Definition: logging2.h:94
int binding_sort(const void *a, const void *b, void *sdata)
Compare two BindingInfo by their keybinding - Implements sort_t -.
Definition: lib.c:405
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:69
Convenience wrapper for the gui headers.
static void dump_message_flags(enum MenuType menu, FILE *fp)
Write out all the message flags.
Definition: help.c:105
static const char * ToCharsDesc[]
Descriptions of the $to_chars flags.
Definition: help.c:85
static const char * CryptCharsDesc[]
Descriptions of the $crypt_chars flags.
Definition: help.c:72
static const char * FlagCharsDesc[]
Descriptions of the $flag_chars flags.
Definition: help.c:53
void mutt_help(enum MenuType menu)
Display the Help Page.
Definition: help.c:149
GUI manage the main index (list of emails)
int measure_column(struct BindingInfoArray *bia, int col)
Measure one column of a table.
Definition: lib.c:419
void gather_menu(enum MenuType menu, struct BindingInfoArray *bia_bind, struct BindingInfoArray *bia_macro)
Gather info about one menu.
Definition: lib.c:624
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition: lib.c:124
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: lib.c:557
int gather_unbound(const struct MenuFuncOp *funcs, const struct KeymapList *km_menu, const struct KeymapList *km_aux, struct BindingInfoArray *bia_unbound)
Gather info about unbound functions for one menu.
Definition: lib.c:441
Manage keymappings.
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
const char * mbtable_get_nth_wchar(const struct MbTable *table, int index)
Extract one char from a multi-byte table.
Definition: mbtable.c:340
#define MAX(a, b)
Definition: memory.h:31
GUI present the user with a selectable list.
Convenience wrapper for the library headers.
#define N_(a)
Definition: message.h:32
#define _(a)
Definition: message.h:28
GUI display a file/email/help in a viewport with paging.
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:71
#define MUTT_PAGER_STRIPES
Striped highlighting.
Definition: lib.h:74
#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:139
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
Prototypes for many functions.
Info about one keybinding.
Definition: lib.h:94
const char * a[3]
Array of info.
Definition: lib.h:95
String manipulation buffer.
Definition: buffer.h:36
Multibyte character table.
Definition: mbtable.h:36
Mapping between a function and an operation.
Definition: lib.h:112
Container for Accounts, Notifications.
Definition: neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:47
Data to be displayed by PagerView.
Definition: lib.h:159
const char * fname
Name of the file to read.
Definition: lib.h:163
Paged view into some data.
Definition: lib.h:170
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:171
enum PagerMode mode
Pager mode.
Definition: lib.h:172
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:173
const char * banner
Title to display in status bar.
Definition: lib.h:174
#define buf_mktemp(buf)
Definition: tmp.h:33
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:37
MenuType
Types of GUI selections.
Definition: type.h:36
@ MENU_INDEX
Index panel (list of emails)
Definition: type.h:47
@ MENU_GENERIC
Generic selection list.
Definition: type.h:46
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:48
@ MENU_EDITOR
Text entry area.
Definition: type.h:44