I made a patch to command.c which changes the operation of the "Save"
command if the current mailbox is a Maildir and maildir_trash is set
to "no".

It will cause the saved message to be immediately unlink()ed and
removed from the screen. The rationale for doing this is that since
the message was Saved, it doesn't need to remain in the mailbox or
take up space on the screen anymore (unlike a message that was
Deleted, which needs to remain around so that you can still undelete
it). The patch is meant to be applied to commands.c in mutt-1.3.26.
There's three things that it does:

When deleting a Maildir message:
  1. unlink() the file of the message immediately
  2. Remove the message from memory
  3. Force a screen redraw

It would be nice if someone more familiar with mutt code (I'm fairly
good with C, but haven't used it much lately and never hacked mutt
before) could take a look at the patch and give me suggestions.

There are three problems with this patch:

- will segfault if I Save the last message in the mailbox

- the "unlink" command affects modification times such that mutt thinks
  an external process was responsible for the modification and will
  erroneously say "New mail in this mailbox." or "Mailbox was externally
  modified."

- The cursor should remain on the same message number (or the previous
  message number, if the last message was deleted). Instead, it
  jumps to another message in a way that I can't predict.

Help?

Here is the patch (apply to commands.c of mutt-1.3.26):

623,653d622
< 
<     /* If this is a Maildir, then delete the message instantly and
<      * make it disappear from the screen. */
<     if (Context->magic == M_MAILDIR && !option (OPTMAILDIRTRASH)) {
<       /* Delete the old message file */
<       char buf[_POSIX_PATH_MAX];
<       int i;
<       snprintf (buf, sizeof (buf), "%s/%s", Context->path, h->path);
<       if (unlink(buf)) {
<         perror("unlink");
<       }
< 
<       /* Remove the message from memory
<        * (some code ripped from mx_update_tables()) */
<       Context->deleted--;
<       Context->size -= (Context->hdrs[h->msgno]->content->length +
<                     Context->hdrs[h->msgno]->content->offset -
<                     Context->hdrs[h->msgno]->content->hdr_offset);
<       /* remove message from the hash tables */
<       if (Context->subj_hash && Context->hdrs[h->msgno]->env->real_subj)
<         hash_delete (Context->subj_hash, Context->hdrs[h->msgno]->env->real_subj, 
Context->hdrs[h->msgno], NULL);
<       if (Context->id_hash && Context->hdrs[h->msgno]->env->message_id)
<         hash_delete (Context->id_hash, Context->hdrs[h->msgno]->env->message_id, 
Context->hdrs[h->msgno], NULL);
<       mutt_free_header (&Context->hdrs[h->msgno]);
<       /* Close the hole in the array */
<       Context->msgcount--;
<       for (i = h->msgno; i < Context->msgcount; i++)
<         Context->hdrs[i] = Context->hdrs[i+1];
<       /* Don't I have to free the memory somehow?
<        * I might have left a memory leak... */
<     }
810,815d778
< 
<     /* If this is a Maildir and saved messages are instantly removed,
<      * we need to trigger a screen redraw. */
<     if (Context->magic == M_MAILDIR && !option (OPTMAILDIRTRASH)) {
<       *redraw |= REDRAW_INDEX;
<     }

Reply via email to