NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
functions.c File Reference

Compose functions. More...

#include "config.h"
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "functions.h"
#include "lib.h"
#include "attach/lib.h"
#include "browser/lib.h"
#include "editor/lib.h"
#include "history/lib.h"
#include "hooks/lib.h"
#include "imap/lib.h"
#include "index/lib.h"
#include "key/lib.h"
#include "menu/lib.h"
#include "ncrypt/lib.h"
#include "nntp/lib.h"
#include "pop/lib.h"
#include "question/lib.h"
#include "send/lib.h"
#include "attach_data.h"
#include "external.h"
#include "globals.h"
#include "module_data.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "mx.h"
#include "nntp/adata.h"
#include "shared_data.h"
#include <libintl.h>
+ Include dependency graph for functions.c:

Go to the source code of this file.

Functions

void compose_init_keys (struct NeoMutt *n, struct SubMenu *sm_generic)
 Initialise the Compose Keybindings - Implements ::init_keys_api.
 
static bool check_count (struct AttachCtx *actx)
 Check if there are any attachments.
 
static char * gen_cid (void)
 Generate a random Content ID.
 
static bool check_cid (const char *cid)
 Check if a Content-ID is valid.
 
static bool content_id_exists (struct AttachCtx *actx, const struct Body *skip, const char *cid)
 Check whether a Content-ID is already in use.
 
static int check_attachments (struct AttachCtx *actx, struct ConfigSubset *sub)
 Check if any attachments have changed or been deleted.
 
static int delete_attachment (struct AttachCtx *actx, int aidx, struct ConfigSubset *sub)
 Delete an attachment.
 
static void update_idx (struct Menu *menu, struct AttachCtx *actx, struct AttachPtr *ap)
 Add a new attachment to the message.
 
static void compose_attach_swap (struct Email *e, struct AttachCtx *actx, int first, int second)
 Swap two adjacent entries in the attachment list.
 
static int body_index (struct AttachCtx *actx, const struct Body *b)
 Find the index of an attachment body.
 
static int prev_sibling (struct AttachCtx *actx, int index)
 Find the previous sibling of an attachment.
 
static int next_sibling (struct AttachCtx *actx, int index)
 Find the next sibling of an attachment.
 
static bool body_array_contains (struct BodyArray *ba, const struct Body *b)
 Does a selection contain a body?
 
static bool selected_attachments_are_siblings (struct Email *e, struct BodyArray *ba)
 Check whether selected attachments are siblings.
 
static MenuRedrawFlags selection_redraw_flags (size_t count)
 Choose redraw flags for a selection.
 
static void resolve_attachment (struct Menu *menu, const struct ConfigSubset *sub, int index, int num)
 Advance the Attachment List selection after an action.
 
static int move_attachment (struct ComposeSharedData *shared, bool up, int count)
 Move attachments in the attachment list.
 
static int group_attachments (struct ComposeSharedData *shared, char *subtype, struct BodyArray *ba)
 Group selected attachments into a multipart group.
 
static int op_attach_attach_file (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Attach files to this message - Implements compose_function_t -.
 
static int op_attach_attach_key (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Attach a PGP public key - Implements compose_function_t -.
 
static int op_attach_attach_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Attach messages to this message - Implements compose_function_t -.
 
static int op_attach_detach (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Delete the current entry - Implements compose_function_t -.
 
static int op_attach_edit_content_id (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the 'Content-ID' of the attachment - Implements compose_function_t -.
 
static int op_attach_edit_description (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment description - Implements compose_function_t -.
 
static int op_attach_edit_encoding (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment transfer-encoding - Implements compose_function_t -.
 
static int op_attach_edit_language (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the 'Content-Language' of the attachment - Implements compose_function_t -.
 
static int op_attach_edit_mime (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment using mailcap entry - Implements compose_function_t -.
 
static int op_attach_edit_type (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit attachment content type - Implements compose_function_t -.
 
static int op_attach_filter (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Filter attachment through a shell command - Implements compose_function_t -.
 
static int op_attach_get_attachment (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Get a temporary copy of an attachment - Implements compose_function_t -.
 
static int op_attach_group_alts (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Group selected attachments as 'multipart/alternative' - Implements compose_function_t -.
 
static int op_attach_group_lingual (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Group selected attachments as 'multipart/multilingual' - Implements compose_function_t -.
 
static int op_attach_group_related (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Group selected attachments as 'multipart/related' - Implements compose_function_t -.
 
static int op_attach_move_down (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Move an attachment down in the attachment list - Implements compose_function_t -.
 
static int op_attach_move_up (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Move an attachment up in the attachment list - Implements compose_function_t -.
 
static int op_attach_new_mime (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Compose new attachment using mailcap entry - Implements compose_function_t -.
 
static int op_attach_print (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Print the current entry - Implements compose_function_t -.
 
static int op_attach_rename_attachment (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Send attachment with a different name - Implements compose_function_t -.
 
static int op_attach_save (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Save message/attachment to a mailbox/file - Implements compose_function_t -.
 
static int op_attach_toggle_disposition (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Toggle disposition between inline/attachment - Implements compose_function_t -.
 
static int op_attach_toggle_recode (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Toggle recoding of this attachment - Implements compose_function_t -.
 
static int op_attach_toggle_unlink (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Toggle whether to delete file after sending it - Implements compose_function_t -.
 
static int op_attach_ungroup (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Ungroup a 'multipart' attachment - Implements compose_function_t -.
 
static int op_attach_update_encoding (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Update an attachment's encoding info - Implements compose_function_t -.
 
static int op_envelope_edit_headers (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the message with headers - Implements compose_function_t -.
 
static int op_compose_edit_file (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the file to be attached - Implements compose_function_t -.
 
static int op_compose_edit_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Edit the message - Implements compose_function_t -.
 
static int op_compose_ispell (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Run ispell on the message - Implements compose_function_t -.
 
static int op_compose_postpone_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Save this message to send later - Implements compose_function_t -.
 
static int op_compose_rename_file (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Rename/move an attached file - Implements compose_function_t -.
 
static int op_compose_send_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Send the message - Implements compose_function_t -.
 
static int op_compose_write_message (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Write the message to a folder - Implements compose_function_t -.
 
static int op_display_headers (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Display message and toggle header weeding - Implements compose_function_t -.
 
static int op_quit (struct ComposeFunctionData *fdata, const struct KeyEvent *event)
 Save changes and exit this dialog - Implements compose_function_t -.
 
int compose_function_dispatcher (struct MuttWindow *win, const struct KeyEvent *event)
 Perform a Compose function - Implements function_dispatcher_t -.
 

Variables

static const struct MenuFuncOp OpCompose []
 Functions for the Compose Menu.
 
static const struct MenuOpSeq ComposeDefaultBindings []
 Key bindings for the Compose Menu.
 
static const struct ComposeFunction ComposeFunctions []
 All the NeoMutt functions that the Compose supports.
 

Detailed Description

Compose functions.

Authors
  • Pietro Cerutti
  • Richard Russon
  • David Purton

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

Function Documentation

◆ compose_init_keys()

void compose_init_keys ( struct NeoMutt * n,
struct SubMenu * sm_generic )

Initialise the Compose Keybindings - Implements ::init_keys_api.

Definition at line 212 of file functions.c.

213{
215 ASSERT(mod_data);
216
217 struct MenuDefinition *md = NULL;
218 struct SubMenu *sm = NULL;
219
221 md = km_register_menu(MENU_COMPOSE, "compose");
222 km_menu_add_submenu(md, sm);
223 km_menu_add_submenu(md, sm_generic);
225
226 mod_data->md_compose = md;
227}
static const struct MenuFuncOp OpCompose[]
Functions for the Compose Menu.
Definition functions.c:78
static const struct MenuOpSeq ComposeDefaultBindings[]
Key bindings for the Compose Menu.
Definition functions.c:150
void km_menu_add_submenu(struct MenuDefinition *md, struct SubMenu *sm)
Add a SubMenu to a Menu Definition.
Definition init.c:123
struct SubMenu * km_register_submenu(const struct MenuFuncOp functions[])
Register a submenu.
Definition init.c:88
struct MenuDefinition * km_register_menu(int menu, const char *name)
Register a menu.
Definition init.c:105
void km_menu_add_bindings(struct MenuDefinition *md, const struct MenuOpSeq bindings[])
Add Keybindings to a Menu.
Definition init.c:136
@ MODULE_ID_COMPOSE
ModuleCompose, Compose an Email
Definition module_api.h:57
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
#define ASSERT(COND)
Definition signal2.h:59
Compose private Module data.
Definition module_data.h:30
struct MenuDefinition * md_compose
Compose Menu Definition.
Definition module_data.h:32
Functions for a Dialog or Window.
Definition menudef.h:44
Collection of related functions.
Definition menudef.h:33
@ MENU_COMPOSE
Compose an email.
Definition type.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_count()

static bool check_count ( struct AttachCtx * actx)
static

Check if there are any attachments.

Parameters
actxAttachment context
Return values
trueThere are attachments

Definition at line 234 of file functions.c.

235{
236 if (actx->idxlen == 0)
237 {
238 mutt_error(_("There are no attachments"));
239 return false;
240 }
241
242 return true;
243}
#define mutt_error(...)
Definition logging2.h:94
#define _(a)
Definition message.h:28
short idxlen
Number of attachmentes.
Definition attach.h:70
+ Here is the caller graph for this function:

◆ gen_cid()

static char * gen_cid ( void )
static

Generate a random Content ID.

Return values
ptrContent ID
Note
The caller should free the string

Definition at line 251 of file functions.c.

252{
253 char rndid[MUTT_RANDTAG_LEN + 1] = { 0 };
254
255 mutt_rand_base32(rndid, sizeof(rndid) - 1);
256 rndid[MUTT_RANDTAG_LEN] = 0;
257
258 return mutt_str_dup(rndid);
259}
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
void mutt_rand_base32(char *buf, size_t buflen)
Fill a buffer with a base32-encoded random string.
Definition random.c:106
#define MUTT_RANDTAG_LEN
Length of random tag for message boundaries.
Definition sendlib.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_cid()

static bool check_cid ( const char * cid)
static

Check if a Content-ID is valid.

Parameters
cidContent-ID to check
Return values
trueContent-ID is valid
falseContent-ID is not valid

Definition at line 267 of file functions.c.

268{
269 static const char *check = "^[-\\.0-9@A-Z_a-z]+$";
270
271 struct Regex *check_cid_regex = mutt_regex_new(check, 0, NULL);
272
273 const bool valid = mutt_regex_match(check_cid_regex, cid);
274
275 mutt_regex_free(&check_cid_regex);
276
277 return valid;
278}
struct Regex * mutt_regex_new(const char *str, uint32_t flags, struct Buffer *err)
Create an Regex from a string.
Definition regex.c:80
void mutt_regex_free(struct Regex **ptr)
Free a Regex object.
Definition regex.c:118
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition regex.c:618
Cached regular expression.
Definition regex3.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ content_id_exists()

static bool content_id_exists ( struct AttachCtx * actx,
const struct Body * skip,
const char * cid )
static

Check whether a Content-ID is already in use.

Parameters
actxAttachment context
skipBody to ignore
cidContent-ID to check
Return values
trueContent-ID already exists

Definition at line 287 of file functions.c.

288{
289 if (!actx || !cid)
290 return false;
291
292 for (int i = 0; i < actx->idxlen; i++)
293 {
294 struct Body *b = actx->idx[i]->body;
295 if ((b == skip) || !b->content_id)
296 continue;
297
298 if (mutt_str_equal(b->content_id, cid))
299 return true;
300 }
301
302 return false;
303}
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
struct AttachPtr ** idx
Array of attachments.
Definition attach.h:69
struct Body * body
Attachment.
Definition attach.h:37
The body of an email.
Definition body.h:36
char * content_id
Content-Id (RFC2392)
Definition body.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_attachments()

static int check_attachments ( struct AttachCtx * actx,
struct ConfigSubset * sub )
static

Check if any attachments have changed or been deleted.

Parameters
actxAttachment context
subConfigSubset
Return values
0Success
-1Error

Definition at line 312 of file functions.c.

313{
314 int rc = -1;
315 struct stat st = { 0 };
316 struct Buffer *pretty = NULL;
317 struct Buffer *msg = NULL;
318
319 for (int i = 0; i < actx->idxlen; i++)
320 {
321 if (actx->idx[i]->body->type == TYPE_MULTIPART)
322 continue;
323 if (stat(actx->idx[i]->body->filename, &st) != 0)
324 {
325 if (!pretty)
326 pretty = buf_pool_get();
327 buf_strcpy(pretty, actx->idx[i]->body->filename);
328 pretty_mailbox(pretty);
329 /* L10N: This message is displayed in the compose menu when an attachment
330 doesn't stat. %d is the attachment number and %s is the attachment
331 filename. The filename is located last to avoid a long path hiding
332 the error message. */
333 mutt_error(_("Attachment #%d no longer exists: %s"), i + 1, buf_string(pretty));
334 goto cleanup;
335 }
336
337 if (actx->idx[i]->body->stamp < st.st_mtime)
338 {
339 if (!pretty)
340 pretty = buf_pool_get();
341 buf_strcpy(pretty, actx->idx[i]->body->filename);
342 pretty_mailbox(pretty);
343
344 if (!msg)
345 msg = buf_pool_get();
346 /* L10N: This message is displayed in the compose menu when an attachment
347 is modified behind the scenes. %d is the attachment number and %s is
348 the attachment filename. The filename is located last to avoid a long
349 path hiding the prompt question. */
350 buf_printf(msg, _("Attachment #%d modified. Update encoding for %s?"),
351 i + 1, buf_string(pretty));
352
354 if (ans == MUTT_YES)
355 mutt_update_encoding(actx->idx[i]->body, sub);
356 else if (ans == MUTT_ABORT)
357 goto cleanup;
358 }
359 }
360
361 rc = 0;
362
363cleanup:
364 buf_pool_release(&pretty);
365 buf_pool_release(&msg);
366 return rc;
367}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:168
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition mime.h:37
void pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition muttlib.c:428
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
QuadOption
Possible values for a quad-option.
Definition quad.h:36
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition quad.h:37
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition quad.h:39
enum QuadOption query_yesorno(const char *prompt, enum QuadOption def)
Ask the user a Yes/No question.
Definition question.c:329
void mutt_update_encoding(struct Body *b, struct ConfigSubset *sub)
Update the encoding type.
Definition sendlib.c:424
time_t stamp
Time stamp of last encoding update.
Definition body.h:77
unsigned int type
content-type primary type, ContentType
Definition body.h:40
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
String manipulation buffer.
Definition buffer.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ delete_attachment()

static int delete_attachment ( struct AttachCtx * actx,
int aidx,
struct ConfigSubset * sub )
static

Delete an attachment.

Parameters
actxAttachment context
aidxIndex number of attachment to delete
subConfig subset
Return values
0Success
-1Error

Definition at line 377 of file functions.c.

378{
379 if (!actx || (aidx < 0) || (aidx >= actx->idxlen))
380 return -1;
381
382 struct AttachPtr **idx = actx->idx;
383 struct Body *b_previous = NULL;
384 struct Body *b_parent = NULL;
385
386 if (aidx == 0)
387 {
388 struct Body *b = actx->idx[0]->body;
389 if (!b->next) // There's only one attachment left
390 {
391 mutt_error(_("You may not delete the only attachment"));
392 return -1;
393 }
394
395 if (cs_subset_bool(sub, "compose_confirm_detach_first"))
396 {
397 /* L10N: Prompt when trying to hit <detach-file> on the first entry in
398 the compose menu. This entry is most likely the message they just
399 typed. Hitting yes will remove the entry and unlink the file, so
400 it's worth confirming they really meant to do it. */
401 enum QuadOption ans = query_yesorno_help(_("Really delete the main message?"), MUTT_NO,
402 sub, "compose_confirm_detach_first");
403 if (ans == MUTT_NO)
404 {
405 idx[aidx]->body->tagged = false;
406 return -1;
407 }
408 }
409 }
410
411 if (idx[aidx]->level > 0)
412 {
413 if (attach_body_parent(idx[0]->body, NULL, idx[aidx]->body, &b_parent))
414 {
415 if (attach_body_count(b_parent->parts, false) < 3)
416 {
417 mutt_error(_("Can't leave group with only one attachment"));
418 return -1;
419 }
420 }
421 }
422
423 // reorder body pointers
424 if (aidx > 0)
425 {
426 if (attach_body_previous(idx[0]->body, idx[aidx]->body, &b_previous))
427 b_previous->next = idx[aidx]->body->next;
428 else if (attach_body_parent(idx[0]->body, NULL, idx[aidx]->body, &b_parent))
429 b_parent->parts = idx[aidx]->body->next;
430 }
431
432 // free memory
433 int part_count = 1;
434 if (aidx < (actx->idxlen - 1))
435 {
436 if ((idx[aidx]->body->type == TYPE_MULTIPART) &&
437 (idx[aidx + 1]->level > idx[aidx]->level))
438 {
439 part_count += attach_body_count(idx[aidx]->body->parts, true);
440 }
441 }
442 idx[aidx]->body->next = NULL;
443 mutt_body_free(&(idx[aidx]->body));
444 for (int i = 0; i < part_count; i++)
445 {
446 FREE(&idx[aidx + i]->tree);
447 FREE(&idx[aidx + i]);
448 }
449
450 // reorder attachment list
451 for (int i = aidx; i < (actx->idxlen - part_count); i++)
452 idx[i] = idx[i + part_count];
453 for (int i = 0; i < part_count; i++)
454 idx[actx->idxlen - i - 1] = NULL;
455 actx->idxlen -= part_count;
456
457 return 0;
458}
bool attach_body_parent(struct Body *start, struct Body *start_parent, struct Body *body, struct Body **body_parent)
Find the parent of a body.
Definition lib.c:71
int attach_body_count(struct Body *body, bool recurse)
Count bodies.
Definition lib.c:42
bool attach_body_previous(struct Body *start, struct Body *body, struct Body **previous)
Find the previous body of a body.
Definition lib.c:142
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition quad.h:38
enum QuadOption query_yesorno_help(const char *prompt, enum QuadOption def, struct ConfigSubset *sub, const char *name)
Ask the user a Yes/No question offering help.
Definition question.c:357
An email to which things will be attached.
Definition attach.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
bool tagged
This attachment is tagged.
Definition body.h:90
struct Body * next
next attachment in the list
Definition body.h:72
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_idx()

static void update_idx ( struct Menu * menu,
struct AttachCtx * actx,
struct AttachPtr * ap )
static

Add a new attachment to the message.

Parameters
menuCurrent menu
actxAttachment context
apAttachment to add

Definition at line 466 of file functions.c.

467{
468 ap->level = 0;
469 for (int i = actx->idxlen; i > 0; i--)
470 {
471 if (ap->level == actx->idx[i - 1]->level)
472 {
473 actx->idx[i - 1]->body->next = ap->body;
474 break;
475 }
476 }
477
478 ap->body->aptr = ap;
479 mutt_actx_add_attach(actx, ap);
480 update_menu(actx, menu, false);
481 menu_set_index(menu, actx->vcount - 1);
482}
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition attach.c:65
void update_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition menu.c:167
short vcount
The number of virtual attachments.
Definition attach.h:74
int level
Nesting depth of attachment.
Definition attach.h:41
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition body.h:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compose_attach_swap()

static void compose_attach_swap ( struct Email * e,
struct AttachCtx * actx,
int first,
int second )
static

Swap two adjacent entries in the attachment list.

Parameters
eEmail
actxAttachment information
firstIndex of first attachment to swap
secondIndex of second attachment to swap

Definition at line 491 of file functions.c.

492{
493 struct AttachPtr **idx = actx->idx;
494
495 // check that attachments really are adjacent
496 if (idx[first]->body->next != idx[second]->body)
497 return;
498
499 // reorder Body pointers
500 if (first == 0)
501 {
502 // first attachment is the fundamental part
503 idx[first]->body->next = idx[second]->body->next;
504 idx[second]->body->next = idx[first]->body;
505 e->body = idx[second]->body;
506 }
507 else
508 {
509 // find previous attachment
510 struct Body *b_previous = NULL;
511 struct Body *b_parent = NULL;
512 if (attach_body_previous(e->body, idx[first]->body, &b_previous))
513 {
514 idx[first]->body->next = idx[second]->body->next;
515 idx[second]->body->next = idx[first]->body;
516 b_previous->next = idx[second]->body;
517 }
518 else if (attach_body_parent(e->body, NULL, idx[first]->body, &b_parent))
519 {
520 idx[first]->body->next = idx[second]->body->next;
521 idx[second]->body->next = idx[first]->body;
522 b_parent->parts = idx[second]->body;
523 }
524 }
525
526 // reorder attachment list
527 struct AttachPtr *saved = idx[second];
528 for (int i = second; i > first; i--)
529 idx[i] = idx[i - 1];
530 idx[first] = saved;
531
532 // if moved attachment is a group then move subparts too
533 if ((idx[first]->body->type == TYPE_MULTIPART) && (second < actx->idxlen - 1))
534 {
535 int i = second + 1;
536 while (idx[i]->level > idx[first]->level)
537 {
538 saved = idx[i];
539 int destidx = i - second + first;
540 for (int j = i; j > destidx; j--)
541 idx[j] = idx[j - 1];
542 idx[destidx] = saved;
543 i++;
544 if (i >= actx->idxlen)
545 break;
546 }
547 }
548}
struct Body * body
List of MIME parts.
Definition email.h:69
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ body_index()

static int body_index ( struct AttachCtx * actx,
const struct Body * b )
static

Find the index of an attachment body.

Parameters
actxAttachment context
bBody to find
Return values
numIndex of body
-1Body wasn't found

Definition at line 557 of file functions.c.

558{
559 if (!actx || !b)
560 return -1;
561
562 for (int i = 0; i < actx->idxlen; i++)
563 {
564 if (actx->idx[i]->body == b)
565 return i;
566 }
567
568 return -1;
569}
+ Here is the caller graph for this function:

◆ prev_sibling()

static int prev_sibling ( struct AttachCtx * actx,
int index )
static

Find the previous sibling of an attachment.

Parameters
actxAttachment context
indexIndex of attachment
Return values
numIndex of previous sibling
-1No previous sibling

Definition at line 578 of file functions.c.

579{
580 if (!actx || (index <= 0) || (index >= actx->idxlen))
581 return -1;
582
583 const int level = actx->idx[index]->level;
584 int previdx = index - 1;
585 while ((previdx > 0) && (actx->idx[previdx]->level > level))
586 previdx--;
587
588 return (actx->idx[previdx]->level == level) ? previdx : -1;
589}
+ Here is the caller graph for this function:

◆ next_sibling()

static int next_sibling ( struct AttachCtx * actx,
int index )
static

Find the next sibling of an attachment.

Parameters
actxAttachment context
indexIndex of attachment
Return values
numIndex of next sibling
-1No next sibling

Definition at line 598 of file functions.c.

599{
600 if (!actx || (index < 0) || (index >= actx->idxlen))
601 return -1;
602
603 const int level = actx->idx[index]->level;
604 int nextidx = index + 1;
605 while ((nextidx < actx->idxlen) && (actx->idx[nextidx]->level > level))
606 nextidx++;
607
608 if ((nextidx >= actx->idxlen) || (actx->idx[nextidx]->level != level))
609 return -1;
610
611 return nextidx;
612}
+ Here is the caller graph for this function:

◆ body_array_contains()

static bool body_array_contains ( struct BodyArray * ba,
const struct Body * b )
static

Does a selection contain a body?

Parameters
baSelected attachments
bBody to find
Return values
trueBody is selected

Definition at line 620 of file functions.c.

621{
622 struct Body **bp = NULL;
623 ARRAY_FOREACH(bp, ba)
624 {
625 if (*bp == b)
626 return true;
627 }
628
629 return false;
630}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
+ Here is the caller graph for this function:

◆ selected_attachments_are_siblings()

static bool selected_attachments_are_siblings ( struct Email * e,
struct BodyArray * ba )
static

Check whether selected attachments are siblings.

Parameters
eEmail
baSelected attachments
Return values
trueSelected attachments are siblings

Definition at line 638 of file functions.c.

639{
640 if (!e || !ba)
641 return false;
642
643 int level = -1;
644 struct Body *parent = NULL;
645 struct Body **bp = NULL;
646 ARRAY_FOREACH(bp, ba)
647 {
648 struct Body *this_parent = NULL;
649 struct Body *body = *bp;
650 if (body->aptr && (body->aptr->level > 0))
651 {
652 if (!attach_body_parent(e->body, NULL, body, &this_parent))
653 return false;
654 }
655
656 if (level == -1)
657 {
658 level = body->aptr ? body->aptr->level : 0;
659 parent = this_parent;
660 continue;
661 }
662
663 if ((level != (body->aptr ? body->aptr->level : 0)) || (parent != this_parent))
664 return false;
665 }
666
667 return true;
668}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ selection_redraw_flags()

static MenuRedrawFlags selection_redraw_flags ( size_t count)
static

Choose redraw flags for a selection.

Parameters
countNumber of selected attachments
Return values
redrawflags for the selection

Definition at line 675 of file functions.c.

676{
677 return (count > 1) ? MENU_REDRAW_FULL : MENU_REDRAW_CURRENT;
678}
@ MENU_REDRAW_FULL
Redraw everything.
Definition lib.h:64
@ MENU_REDRAW_CURRENT
Redraw the current line of the menu.
Definition lib.h:63
+ Here is the caller graph for this function:

◆ resolve_attachment()

static void resolve_attachment ( struct Menu * menu,
const struct ConfigSubset * sub,
int index,
int num )
static

Advance the Attachment List selection after an action.

Parameters
menuMenu
subConfig subset
indexOriginal menu index, before the action
numNumber of selected attachment entries operated on

If $resolve is set, move the selection on by the number of items that were acted upon. Overruns are silently capped at the end of the list.

Nothing is moved when operating on a tag-prefix selection.

Definition at line 692 of file functions.c.

694{
695 if (!menu || menu->tag_prefix || (num <= 0))
696 return;
697
698 const bool c_resolve = cs_subset_bool(sub, "resolve");
699 if (!c_resolve)
700 return;
701
702 const int new_index = index + num;
703 if (new_index < menu->max)
704 menu_set_index(menu, new_index);
705}
bool tag_prefix
User has pressed <tag-prefix>
Definition lib.h:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ move_attachment()

static int move_attachment ( struct ComposeSharedData * shared,
bool up,
int count )
static

Move attachments in the attachment list.

Parameters
sharedShared compose data
upIf true, move up, otherwise move down
countRepeat-count
Return values
enumFunctionRetval

Definition at line 714 of file functions.c.

715{
716 struct AttachCtx *actx = shared->adata->actx;
717 if (!check_count(actx))
718 return FR_ERROR;
719
720 struct Menu *menu = shared->adata->menu;
721 struct AttachPtr *cur_att = current_attachment(actx, menu);
722 if (!cur_att)
723 return FR_ERROR;
724
725 struct Body *cur_body = cur_att->body;
726 struct BodyArray ba = ARRAY_HEAD_INITIALIZER;
727 ba_add_selection(&ba, actx, menu, menu->tag_prefix, count);
728 if (ARRAY_EMPTY(&ba))
729 goto done;
730
731 if ((ARRAY_SIZE(&ba) > 1) && !selected_attachments_are_siblings(shared->email, &ba))
732 {
733 mutt_error(_("Selected attachments must be siblings"));
734 ARRAY_FREE(&ba);
735 return FR_ERROR;
736 }
737
738 bool moved = false;
739 if (up)
740 {
741 struct Body **bp = NULL;
742 ARRAY_FOREACH(bp, &ba)
743 {
744 const int index = body_index(actx, *bp);
745 const int previdx = prev_sibling(actx, index);
746 if (previdx < 0)
747 continue;
748 if (body_array_contains(&ba, actx->idx[previdx]->body))
749 continue;
750
751 compose_attach_swap(shared->email, actx, previdx, index);
752 moved = true;
753 }
754 }
755 else
756 {
757 for (int i = ARRAY_SIZE(&ba) - 1; i >= 0; i--)
758 {
759 struct Body **bp = ARRAY_GET(&ba, i);
760 const int index = body_index(actx, *bp);
761 const int nextidx = next_sibling(actx, index);
762 if (nextidx < 0)
763 continue;
764 if (body_array_contains(&ba, actx->idx[nextidx]->body))
765 continue;
766
767 compose_attach_swap(shared->email, actx, index, nextidx);
768 moved = true;
769 }
770 }
771
772 if (!moved)
773 {
774 mutt_error(up ? _("Attachment is already at top") : _("Attachment is already at bottom"));
775 goto done;
776 }
777
778 mutt_update_tree(actx);
781
782 const int index = body_index(actx, cur_body);
783 if (index >= 0)
784 menu_set_index(menu, index);
785
786 ARRAY_FREE(&ba);
787 return FR_SUCCESS;
788
789done:
790 ARRAY_FREE(&ba);
791 return FR_ERROR;
792}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
static bool check_count(struct AttachCtx *actx)
Check if there are any attachments.
Definition functions.c:234
static int body_index(struct AttachCtx *actx, const struct Body *b)
Find the index of an attachment body.
Definition functions.c:557
static int prev_sibling(struct AttachCtx *actx, int index)
Find the previous sibling of an attachment.
Definition functions.c:578
static void compose_attach_swap(struct Email *e, struct AttachCtx *actx, int first, int second)
Swap two adjacent entries in the attachment list.
Definition functions.c:491
static bool body_array_contains(struct BodyArray *ba, const struct Body *b)
Does a selection contain a body?
Definition functions.c:620
static int next_sibling(struct AttachCtx *actx, int index)
Find the next sibling of an attachment.
Definition functions.c:598
static bool selected_attachments_are_siblings(struct Email *e, struct BodyArray *ba)
Check whether selected attachments are siblings.
Definition functions.c:638
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:40
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:39
@ NT_EMAIL_CHANGE_ATTACH
Email's Attachments have changed.
Definition email.h:188
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition menu.c:177
@ MENU_REDRAW_INDEX
Redraw the index.
Definition lib.h:61
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition notify.c:173
@ NT_EMAIL
Email has changed, NotifyEmail, EventEmail.
Definition notify_type.h:44
struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition recvattach.c:71
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition recvattach.c:118
int ba_add_selection(struct BodyArray *ba, struct AttachCtx *actx, struct Menu *menu, bool use_tagged, int count)
Build a working set of attachment bodies for an action.
Definition selection.c:164
A set of attachments.
Definition attach.h:65
struct Menu * menu
Menu displaying the attachments.
Definition attach_data.h:35
struct AttachCtx * actx
Set of attachments.
Definition attach_data.h:34
struct ComposeAttachData * adata
Attachments.
Definition shared_data.h:39
struct Email * email
Email being composed.
Definition shared_data.h:38
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition email.h:73
Definition lib.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_attachments()

static int group_attachments ( struct ComposeSharedData * shared,
char * subtype,
struct BodyArray * ba )
static

Group selected attachments into a multipart group.

Parameters
sharedShared compose data
subtypeMIME subtype
baSelected attachments
Return values
FR_SUCCESSSuccess
FR_ERRORFailure

Definition at line 802 of file functions.c.

804{
805 struct AttachCtx *actx = shared->adata->actx;
806 int group_level = -1;
807 struct Body *bptr_parent = NULL;
808
809 // Attachments to be grouped must have the same parent
810 for (int i = 0; i < actx->idxlen; i++)
811 {
812 if (body_array_contains(ba, actx->idx[i]->body))
813 {
814 if (group_level == -1)
815 {
816 group_level = actx->idx[i]->level;
817 }
818 else
819 {
820 if (group_level != actx->idx[i]->level)
821 {
822 mutt_error(_("Attachments to be grouped must have the same parent"));
823 return FR_ERROR;
824 }
825 }
826 // if not at top level check if all tagged attachments have same parent
827 if (group_level > 0)
828 {
829 if (bptr_parent)
830 {
831 struct Body *bptr_test = NULL;
832 if (!attach_body_parent(actx->idx[0]->body, NULL, actx->idx[i]->body, &bptr_test))
833 mutt_debug(LL_DEBUG5, "can't find parent\n");
834 if (bptr_test != bptr_parent)
835 {
836 mutt_error(_("Attachments to be grouped must have the same parent"));
837 return FR_ERROR;
838 }
839 }
840 else
841 {
842 if (!attach_body_parent(actx->idx[0]->body, NULL, actx->idx[i]->body, &bptr_parent))
843 mutt_debug(LL_DEBUG5, "can't find parent\n");
844 }
845 }
846 }
847 }
848
849 // Can't group all attachments unless at top level
850 if (bptr_parent)
851 {
852 if (ARRAY_SIZE(ba) == attach_body_count(bptr_parent->parts, false))
853 {
854 mutt_error(_("Can't leave group with only one attachment"));
855 return FR_ERROR;
856 }
857 }
858
859 struct Body *group = mutt_body_new();
860 group->type = TYPE_MULTIPART;
861 group->subtype = mutt_str_dup(subtype);
862 group->encoding = ENC_7BIT;
863
864 struct Body *bptr_first = NULL; // first selected attachment
865 struct Body *bptr = NULL; // current selected attachment
866 struct Body *group_parent = NULL; // parent of group
867 struct Body *group_previous = NULL; // previous body to group
868 struct Body *group_part = NULL; // current attachment in group
869 int group_idx = 0; // index in attachment list where group will be inserted
870 int group_last_idx = 0; // index of last part of previous found group
871 int group_parent_type = TYPE_OTHER;
872
873 for (int i = 0; i < actx->idxlen; i++)
874 {
875 bptr = actx->idx[i]->body;
876 if (body_array_contains(ba, bptr))
877 {
878 // set group properties based on first selected attachment
879 if (!bptr_first)
880 {
881 group->disposition = bptr->disposition;
882 if (bptr->language && !mutt_str_equal(subtype, "multilingual"))
883 group->language = mutt_str_dup(bptr->language);
884 group_parent_type = bptr->aptr->parent_type;
885 bptr_first = bptr;
886 if (i > 0)
887 {
888 if (!attach_body_previous(shared->email->body, bptr, &group_previous))
889 {
890 mutt_debug(LL_DEBUG5, "couldn't find previous\n");
891 }
892 if (!attach_body_parent(shared->email->body, NULL, bptr, &group_parent))
893 {
894 mutt_debug(LL_DEBUG5, "couldn't find parent\n");
895 }
896 }
897 }
898
899 if (bptr->tagged)
900 {
901 shared->adata->menu->num_tagged--;
902 bptr->tagged = false;
903 }
904 bptr->aptr->level++;
906
907 // append bptr to the group parts list and remove from email body list
908 struct Body *bptr_previous = NULL;
909 if (attach_body_previous(shared->email->body, bptr, &bptr_previous))
910 bptr_previous->next = bptr->next;
911 else if (attach_body_parent(shared->email->body, NULL, bptr, &bptr_parent))
912 bptr_parent->parts = bptr->next;
913 else
914 shared->email->body = bptr->next;
915
916 if (group_part)
917 {
918 // add bptr to group parts list
919 group_part->next = bptr;
920 group_part = group_part->next;
921 group_part->next = NULL;
922
923 // reorder attachments and set levels
924 int bptr_attachments = attach_body_count(bptr, true);
925 for (int j = i + 1; j < (i + bptr_attachments); j++)
926 actx->idx[j]->level++;
927 if (i > (group_last_idx + 1))
928 {
929 for (int j = 0; j < bptr_attachments; j++)
930 {
931 struct AttachPtr *saved = actx->idx[i + bptr_attachments - 1];
932 for (int k = i + bptr_attachments - 1; k > (group_last_idx + 1); k--)
933 actx->idx[k] = actx->idx[k - 1];
934 actx->idx[group_last_idx + 1] = saved;
935 }
936 }
937 i += bptr_attachments - 1;
938 group_last_idx += bptr_attachments;
939 }
940 else
941 {
942 group_idx = i;
943 group->parts = bptr;
944 group_part = bptr;
945 group_part->next = NULL;
946 int bptr_attachments = attach_body_count(bptr, true);
947 for (int j = i + 1; j < (i + bptr_attachments); j++)
948 actx->idx[j]->level++;
949 i += bptr_attachments - 1;
950 group_last_idx = i;
951 }
952 }
953 }
954
955 if (!bptr_first)
956 {
957 mutt_body_free(&group);
958 return FR_ERROR;
959 }
960
961 // set group->next
962 int next_aidx = group_idx + attach_body_count(group->parts, true);
963 if (group_parent)
964 {
965 // find next attachment with the same parent as the group
966 struct Body *b = NULL;
967 struct Body *b_parent = NULL;
968 while (next_aidx < actx->idxlen)
969 {
970 b = actx->idx[next_aidx]->body;
971 b_parent = NULL;
972 if (attach_body_parent(shared->email->body, NULL, b, &b_parent))
973 {
974 if (group_parent == b_parent)
975 {
976 group->next = b;
977 break;
978 }
979 }
980 next_aidx++;
981 }
982 }
983 else if (next_aidx < actx->idxlen)
984 {
985 // group is at top level
986 group->next = actx->idx[next_aidx]->body;
987 }
988
989 // set previous or parent for group
990 if (group_previous)
991 group_previous->next = group;
992 else if (group_parent)
993 group_parent->parts = group;
994
996
997 struct AttachPtr *group_ap = mutt_aptr_new();
998 group_ap->body = group;
999 group_ap->body->aptr = group_ap;
1000 group_ap->level = group_level;
1001 group_ap->parent_type = group_parent_type;
1002
1003 // insert group into attachment list
1004 mutt_actx_ins_attach(actx, group_ap, group_idx);
1005
1006 // update email body and last attachment pointers
1007 shared->email->body = actx->idx[0]->body;
1008 actx->idx[actx->idxlen - 1]->body->next = NULL;
1009
1010 update_menu(actx, shared->adata->menu, false);
1011 shared->adata->menu->current = group_idx;
1013
1014 exec_message_hook(NULL, shared->email, CMD_SEND2_HOOK);
1015 return FR_SUCCESS;
1016}
void mutt_actx_ins_attach(struct AttachCtx *actx, struct AttachPtr *attach, int aidx)
Insert an Attachment into an Attachment Context at Specified Index.
Definition attach.c:91
struct AttachPtr * mutt_aptr_new(void)
Create a new Attachment Pointer.
Definition attach.c:40
@ CMD_SEND2_HOOK
:send2-hook
Definition command.h:109
struct Body * mutt_body_new(void)
Create a new Body.
Definition body.c:44
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
void exec_message_hook(struct Mailbox *m, struct Email *e, enum CommandId id)
Perform a message hook.
Definition exec.c:137
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
@ ENC_7BIT
7-bit text
Definition mime.h:49
@ TYPE_OTHER
Unknown Content-Type.
Definition mime.h:31
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
Definition multipart.c:93
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition attach.h:39
char * language
content-language (RFC8255)
Definition body.h:78
struct ParameterList parameter
Parameters of the content-type.
Definition body.h:63
unsigned int disposition
content-disposition, ContentDisposition
Definition body.h:42
char * subtype
content-type subtype
Definition body.h:61
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
int current
Current entry.
Definition lib.h:87
int num_tagged
Number of tagged entries.
Definition lib.h:101
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ OpCompose

const struct MenuFuncOp OpCompose[]
static

Functions for the Compose Menu.

Definition at line 78 of file functions.c.

78 { /* map: compose */
79 { "attach-file", OP_ATTACH_ATTACH_FILE },
80 { "attach-key", OP_ATTACH_ATTACH_KEY },
81 { "attach-message", OP_ATTACH_ATTACH_MESSAGE },
82 { "attach-news-message", OP_ATTACH_ATTACH_NEWS_MESSAGE },
83#ifdef USE_AUTOCRYPT
84 { "autocrypt-menu", OP_COMPOSE_AUTOCRYPT_MENU },
85#endif
86 { "copy-file", OP_ATTACH_SAVE },
87 { "detach-file", OP_ATTACH_DETACH },
88 { "display-toggle-weed", OP_DISPLAY_HEADERS },
89 { "edit-bcc", OP_ENVELOPE_EDIT_BCC },
90 { "edit-cc", OP_ENVELOPE_EDIT_CC },
91 { "edit-content-id", OP_ATTACH_EDIT_CONTENT_ID },
92 { "edit-description", OP_ATTACH_EDIT_DESCRIPTION },
93 { "edit-encoding", OP_ATTACH_EDIT_ENCODING },
94 { "edit-fcc", OP_ENVELOPE_EDIT_FCC },
95 { "edit-file", OP_COMPOSE_EDIT_FILE },
96 { "edit-followup-to", OP_ENVELOPE_EDIT_FOLLOWUP_TO },
97 { "edit-from", OP_ENVELOPE_EDIT_FROM },
98 { "edit-headers", OP_ENVELOPE_EDIT_HEADERS },
99 { "edit-language", OP_ATTACH_EDIT_LANGUAGE },
100 { "edit-message", OP_COMPOSE_EDIT_MESSAGE },
101 { "edit-mime", OP_ATTACH_EDIT_MIME },
102 { "edit-newsgroups", OP_ENVELOPE_EDIT_NEWSGROUPS },
103 { "edit-reply-to", OP_ENVELOPE_EDIT_REPLY_TO },
104 { "edit-subject", OP_ENVELOPE_EDIT_SUBJECT },
105 { "edit-to", OP_ENVELOPE_EDIT_TO },
106 { "edit-type", OP_ATTACH_EDIT_TYPE },
107 { "edit-x-comment-to", OP_ENVELOPE_EDIT_X_COMMENT_TO },
108 { "filter-entry", OP_ATTACH_FILTER },
109 { "get-attachment", OP_ATTACH_GET_ATTACHMENT },
110 { "group-alternatives", OP_ATTACH_GROUP_ALTS },
111 { "group-multilingual", OP_ATTACH_GROUP_LINGUAL },
112 { "group-related", OP_ATTACH_GROUP_RELATED },
113 { "ispell", OP_COMPOSE_ISPELL },
114 { "move-down", OP_ATTACH_MOVE_DOWN },
115 { "move-up", OP_ATTACH_MOVE_UP },
116 { "new-mime", OP_ATTACH_NEW_MIME },
117 { "pgp-menu", OP_COMPOSE_PGP_MENU },
118 { "pipe-entry", OP_PIPE },
119 { "pipe-message", OP_PIPE },
120 { "postpone-message", OP_COMPOSE_POSTPONE_MESSAGE },
121 { "preview-scroll-half-down", OP_PREVIEW_SCROLL_HALF_DOWN },
122 { "preview-scroll-half-up", OP_PREVIEW_SCROLL_HALF_UP },
123 { "preview-scroll-line-down", OP_PREVIEW_SCROLL_LINE_DOWN },
124 { "preview-scroll-line-up", OP_PREVIEW_SCROLL_LINE_UP },
125 { "preview-scroll-page-down", OP_PREVIEW_SCROLL_PAGE_DOWN },
126 { "preview-scroll-page-up", OP_PREVIEW_SCROLL_PAGE_UP },
127 { "preview-select-first-entry", OP_PREVIEW_SELECT_FIRST_ENTRY },
128 { "preview-select-last-entry", OP_PREVIEW_SELECT_LAST_ENTRY },
129 { "print-entry", OP_ATTACH_PRINT },
130 { "rename-attachment", OP_ATTACH_RENAME_ATTACHMENT },
131 { "rename-file", OP_COMPOSE_RENAME_FILE },
132 { "send-message", OP_COMPOSE_SEND_MESSAGE },
133 { "smime-menu", OP_COMPOSE_SMIME_MENU },
134 { "toggle-disposition", OP_ATTACH_TOGGLE_DISPOSITION },
135 { "toggle-recode", OP_ATTACH_TOGGLE_RECODE },
136 { "toggle-unlink", OP_ATTACH_TOGGLE_UNLINK },
137 { "ungroup-attachment", OP_ATTACH_UNGROUP },
138 { "update-encoding", OP_ATTACH_UPDATE_ENCODING },
139 { "view-attach", OP_ATTACH_VIEW },
140 { "view-mailcap", OP_ATTACH_VIEW_MAILCAP },
141 { "view-pager", OP_ATTACH_VIEW_PAGER },
142 { "view-text", OP_ATTACH_VIEW_TEXT },
143 { "write-fcc", OP_COMPOSE_WRITE_MESSAGE },
144 { NULL, 0 },
145};

◆ ComposeDefaultBindings

const struct MenuOpSeq ComposeDefaultBindings[]
static

Key bindings for the Compose Menu.

Definition at line 150 of file functions.c.

150 { /* map: compose */
151 { OP_ATTACH_ATTACH_FILE, "a" },
152 { OP_ATTACH_ATTACH_KEY, "\033k" }, // <Alt-k>
153 { OP_ATTACH_ATTACH_MESSAGE, "A" },
154 { OP_ATTACH_DETACH, "D" },
155 { OP_ATTACH_EDIT_CONTENT_ID, "\033i" }, // <Alt-i>
156 { OP_ATTACH_EDIT_DESCRIPTION, "d" },
157 { OP_ATTACH_EDIT_ENCODING, "\005" }, // <Ctrl-E>
158 { OP_ATTACH_EDIT_LANGUAGE, "\014" }, // <Ctrl-L>
159 { OP_ATTACH_EDIT_MIME, "m" },
160 { OP_ATTACH_EDIT_TYPE, "\024" }, // <Ctrl-T>
161 { OP_ATTACH_FILTER, "F" },
162 { OP_ATTACH_GET_ATTACHMENT, "G" },
163 { OP_ATTACH_GROUP_ALTS, "&" },
164 { OP_ATTACH_GROUP_LINGUAL, "^" },
165 { OP_ATTACH_GROUP_RELATED, "%" },
166 { OP_ATTACH_MOVE_DOWN, "+" },
167 { OP_ATTACH_MOVE_UP, "-" },
168 { OP_ATTACH_NEW_MIME, "n" },
169 { OP_PIPE, "|" },
170 { OP_ATTACH_PRINT, "l" },
171 { OP_ATTACH_RENAME_ATTACHMENT, "\017" }, // <Ctrl-O>
172 { OP_ATTACH_SAVE, "C" },
173 { OP_ATTACH_TOGGLE_DISPOSITION, "\004" }, // <Ctrl-D>
174 { OP_ATTACH_TOGGLE_UNLINK, "u" },
175 { OP_ATTACH_UNGROUP, "#" },
176 { OP_ATTACH_UPDATE_ENCODING, "U" },
177 { OP_ATTACH_VIEW, "<keypadenter>" },
178 { OP_ATTACH_VIEW, "\n" }, // <Enter>
179 { OP_ATTACH_VIEW, "\r" }, // <Return>
180#ifdef USE_AUTOCRYPT
181 { OP_COMPOSE_AUTOCRYPT_MENU, "o" },
182#endif
183 { OP_COMPOSE_EDIT_FILE, "\033e" }, // <Alt-e>
184 { OP_COMPOSE_EDIT_MESSAGE, "e" },
185 { OP_COMPOSE_ISPELL, "i" },
186 { OP_COMPOSE_PGP_MENU, "p" },
187 { OP_COMPOSE_POSTPONE_MESSAGE, "P" },
188 { OP_COMPOSE_RENAME_FILE, "R" },
189 { OP_COMPOSE_SEND_MESSAGE, "y" },
190 { OP_COMPOSE_SMIME_MENU, "S" },
191 { OP_COMPOSE_WRITE_MESSAGE, "w" },
192 { OP_DISPLAY_HEADERS, "h" },
193 { OP_ENVELOPE_EDIT_BCC, "b" },
194 { OP_ENVELOPE_EDIT_CC, "c" },
195 { OP_ENVELOPE_EDIT_FCC, "f" },
196 { OP_ENVELOPE_EDIT_FROM, "\033f" }, // <Alt-f>
197 { OP_ENVELOPE_EDIT_HEADERS, "E" },
198 { OP_ENVELOPE_EDIT_REPLY_TO, "r" },
199 { OP_ENVELOPE_EDIT_SUBJECT, "s" },
200 { OP_ENVELOPE_EDIT_TO, "t" },
201 { OP_PREVIEW_SCROLL_PAGE_DOWN, "<pagedown>" },
202 { OP_PREVIEW_SCROLL_PAGE_UP, "<pageup>" },
203 { OP_FORGET_PASSPHRASE, "\006" }, // <Ctrl-F>
204 { OP_TAG, "T" },
205 { 0, NULL },
206};

◆ ComposeFunctions

const struct ComposeFunction ComposeFunctions[]
static

All the NeoMutt functions that the Compose supports.

Definition at line 2729 of file functions.c.

2729 {
2730 // clang-format off
2731 { OP_ATTACH_ATTACH_FILE, op_attach_attach_file },
2732 { OP_ATTACH_ATTACH_KEY, op_attach_attach_key },
2733 { OP_ATTACH_ATTACH_MESSAGE, op_attach_attach_message },
2734 { OP_ATTACH_ATTACH_NEWS_MESSAGE, op_attach_attach_message },
2735 { OP_ATTACH_DETACH, op_attach_detach },
2736 { OP_ATTACH_EDIT_CONTENT_ID, op_attach_edit_content_id },
2737 { OP_ATTACH_EDIT_DESCRIPTION, op_attach_edit_description },
2738 { OP_ATTACH_EDIT_ENCODING, op_attach_edit_encoding },
2739 { OP_ATTACH_EDIT_LANGUAGE, op_attach_edit_language },
2740 { OP_ATTACH_EDIT_MIME, op_attach_edit_mime },
2741 { OP_ATTACH_EDIT_TYPE, op_attach_edit_type },
2742 { OP_ATTACH_FILTER, op_attach_filter },
2743 { OP_ATTACH_GET_ATTACHMENT, op_attach_get_attachment },
2744 { OP_ATTACH_GROUP_ALTS, op_attach_group_alts },
2745 { OP_ATTACH_GROUP_LINGUAL, op_attach_group_lingual },
2746 { OP_ATTACH_GROUP_RELATED, op_attach_group_related },
2747 { OP_ATTACH_MOVE_DOWN, op_attach_move_down },
2748 { OP_ATTACH_MOVE_UP, op_attach_move_up },
2749 { OP_ATTACH_NEW_MIME, op_attach_new_mime },
2750 { OP_ATTACH_PRINT, op_attach_print },
2751 { OP_ATTACH_RENAME_ATTACHMENT, op_attach_rename_attachment },
2752 { OP_ATTACH_SAVE, op_attach_save },
2753 { OP_ATTACH_TOGGLE_DISPOSITION, op_attach_toggle_disposition },
2754 { OP_ATTACH_TOGGLE_RECODE, op_attach_toggle_recode },
2755 { OP_ATTACH_TOGGLE_UNLINK, op_attach_toggle_unlink },
2756 { OP_ATTACH_UNGROUP, op_attach_ungroup },
2757 { OP_ATTACH_UPDATE_ENCODING, op_attach_update_encoding },
2758 { OP_ATTACH_VIEW, op_display_headers },
2759 { OP_ATTACH_VIEW_MAILCAP, op_display_headers },
2760 { OP_ATTACH_VIEW_PAGER, op_display_headers },
2761 { OP_ATTACH_VIEW_TEXT, op_display_headers },
2762 { OP_COMPOSE_EDIT_FILE, op_compose_edit_file },
2763 { OP_COMPOSE_EDIT_MESSAGE, op_compose_edit_message },
2764 { OP_COMPOSE_ISPELL, op_compose_ispell },
2765 { OP_COMPOSE_POSTPONE_MESSAGE, op_compose_postpone_message },
2766 { OP_COMPOSE_RENAME_FILE, op_compose_rename_file },
2767 { OP_COMPOSE_SEND_MESSAGE, op_compose_send_message },
2768 { OP_COMPOSE_WRITE_MESSAGE, op_compose_write_message },
2769 { OP_DISPLAY_HEADERS, op_display_headers },
2770 { OP_ENVELOPE_EDIT_HEADERS, op_envelope_edit_headers },
2771 { OP_EXIT, op_quit },
2772 { OP_PIPE, op_attach_filter },
2773 { OP_QUIT, op_quit },
2774 { 0, NULL },
2775 // clang-format on
2776};
static int op_quit(struct AliasFunctionData *fdata, const struct KeyEvent *event)
Save changes and exit this dialog - Implements alias_function_t -.
Definition functions.c:308
static int op_attach_edit_type(struct AttachFunctionData *fdata, const struct KeyEvent *event)
edit attachment content type - Implements attach_function_t -
Definition functions.c:391
static int op_attach_save(struct AttachFunctionData *fdata, const struct KeyEvent *event)
save message/attachment to a mailbox/file - Implements attach_function_t -
Definition functions.c:428
static int op_attach_print(struct AttachFunctionData *fdata, const struct KeyEvent *event)
print the current entry - Implements attach_function_t -
Definition functions.c:415
static int op_attach_edit_description(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit attachment description - Implements compose_function_t -.
Definition functions.c:1449
static int op_compose_postpone_message(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Save this message to send later - Implements compose_function_t -.
Definition functions.c:2501
static int op_attach_edit_content_id(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit the 'Content-ID' of the attachment - Implements compose_function_t -.
Definition functions.c:1361
static int op_attach_group_lingual(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Group selected attachments as 'multipart/multilingual' - Implements compose_function_t -.
Definition functions.c:1791
static int op_compose_write_message(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Write the message to a folder - Implements compose_function_t -.
Definition functions.c:2598
static int op_compose_edit_message(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit the message - Implements compose_function_t -.
Definition functions.c:2451
static int op_attach_ungroup(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Ungroup a 'multipart' attachment - Implements compose_function_t -.
Definition functions.c:2274
static int op_compose_ispell(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Run ispell on the message - Implements compose_function_t -.
Definition functions.c:2475
static int op_attach_update_encoding(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Update an attachment's encoding info - Implements compose_function_t -.
Definition functions.c:2337
static int op_attach_get_attachment(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Get a temporary copy of an attachment - Implements compose_function_t -.
Definition functions.c:1724
static int op_attach_group_related(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Group selected attachments as 'multipart/related' - Implements compose_function_t -.
Definition functions.c:1832
static int op_compose_rename_file(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Rename/move an attached file - Implements compose_function_t -.
Definition functions.c:2518
static int op_attach_move_up(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Move an attachment up in the attachment list - Implements compose_function_t -.
Definition functions.c:1927
static int op_attach_filter(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Filter attachment through a shell command - Implements compose_function_t -.
Definition functions.c:1685
static int op_attach_edit_language(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit the 'Content-Language' of the attachment - Implements compose_function_t -.
Definition functions.c:1563
static int op_attach_toggle_disposition(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Toggle disposition between inline/attachment - Implements compose_function_t -.
Definition functions.c:2146
static int op_attach_rename_attachment(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Send attachment with a different name - Implements compose_function_t -.
Definition functions.c:2082
static int op_attach_move_down(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Move an attachment down in the attachment list - Implements compose_function_t -.
Definition functions.c:1867
static int op_attach_group_alts(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Group selected attachments as 'multipart/alternative' - Implements compose_function_t -.
Definition functions.c:1770
static int op_attach_attach_key(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Attach a PGP public key - Implements compose_function_t -.
Definition functions.c:1089
static int op_attach_toggle_recode(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Toggle recoding of this attachment - Implements compose_function_t -.
Definition functions.c:2183
static int op_envelope_edit_headers(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit the message with headers - Implements compose_function_t -.
Definition functions.c:2376
static int op_compose_send_message(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Send the message - Implements compose_function_t -.
Definition functions.c:2569
static int op_attach_edit_encoding(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit attachment transfer-encoding - Implements compose_function_t -.
Definition functions.c:1500
static int op_attach_toggle_unlink(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Toggle whether to delete file after sending it - Implements compose_function_t -.
Definition functions.c:2238
static int op_attach_detach(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Delete the current entry - Implements compose_function_t -.
Definition functions.c:1271
static int op_display_headers(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Display message and toggle header weeding - Implements compose_function_t -.
Definition functions.c:2642
static int op_attach_attach_message(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Attach messages to this message - Implements compose_function_t -.
Definition functions.c:1118
static int op_compose_edit_file(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit the file to be attached - Implements compose_function_t -.
Definition functions.c:2426
static int op_attach_edit_mime(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Edit attachment using mailcap entry - Implements compose_function_t -.
Definition functions.c:1619
static int op_attach_new_mime(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Compose new attachment using mailcap entry - Implements compose_function_t -.
Definition functions.c:1966
static int op_attach_attach_file(struct ComposeFunctionData *fdata, const struct KeyEvent *event)
Attach files to this message - Implements compose_function_t -.
Definition functions.c:1023