3
0
Fork 0
forked from mirrors/nixpkgs

mutt: 1.5.23 -> 1.5.24

This change uses a different patchset for mutt-with-sidebar.
This commit is contained in:
Moritz Ulrich 2015-09-29 00:23:55 +02:00
parent e916273209
commit 47c92a87c8
9 changed files with 2409 additions and 8 deletions

View file

@ -17,14 +17,14 @@ assert saslSupport -> cyrus_sasl != null;
assert gpgmeSupport -> gpgme != null;
let
version = "1.5.23";
version = "1.5.24";
in
stdenv.mkDerivation rec {
name = "mutt${stdenv.lib.optionalString withSidebar "-with-sidebar"}-${version}";
src = fetchurl {
url = "mirror://sourceforge/mutt/mutt-${version}.tar.gz";
sha256 = "0dzx4qk50pjfsb6cs5jahng96a52k12f7pm0sc78iqdrawg71w1s";
url = "http://ftp.mutt.org/pub/mutt/mutt-${version}.tar.gz";
sha256 = "0012njrgxf1barjksqkx7ccid2l0xyikhna9mjs9vcfpbrvcm4m2";
};
buildInputs = with stdenv.lib;
@ -59,11 +59,16 @@ stdenv.mkDerivation rec {
];
# Adding the sidebar
patches = [] ++
(stdenv.lib.optional withSidebar (fetchurl {
url = http://lunar-linux.org/~tchan/mutt/patch-1.5.23.sidebar.20140412.txt;
sha256 = "1i2r7dj0pd1k0z3jjxn2szi6sf0k28i8dwhr4f65pn8r2lh3wisz";
}));
patches = stdenv.lib.optional withSidebar [
./trash-folder.patch
./sidebar.patch
./sidebar-dotpathsep.patch
./sidebar-utf8.patch
./sidebar-newonly.patch
./sidebar-delimnullwide.patch
./sidebar-compose.patch
./sidebar-new.patch
];
meta = with stdenv.lib; {
description = "A small but very powerful text-based mail client";

View file

@ -0,0 +1,40 @@
From: Evgeni Golov <evgeni@debian.org>
Date: Fri, 14 Mar 2014 08:54:47 +0100
Subject: sidebar-compose
draw_sidebar sets SidebarWidth to 0 when sidebar_visible is false.
However, if you start mutt in compose mode, draw_sidebar won't be
called until the next redraw and your header lines will be off by
the width of the sidebar, even when you did not want a sidebar at
all.
Can be tested with:
HOME=/ LC_ALL=C mutt -e 'unset sidebar_visible' -s test recipient
Closes: #502627
Gbp-Pq: Topic mutt-patched
---
compose.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/compose.c b/compose.c
index b63695f..0fa6df2 100644
--- a/compose.c
+++ b/compose.c
@@ -32,6 +32,7 @@
#include "mailbox.h"
#include "sort.h"
#include "charset.h"
+#include "sidebar.h"
#ifdef MIXMASTER
#include "remailer.h"
@@ -248,6 +249,7 @@ static void draw_envelope_addr (int line, ADDRESS *addr)
static void draw_envelope (HEADER *msg, char *fcc)
{
+ draw_sidebar (MENU_COMPOSE);
draw_envelope_addr (HDR_FROM, msg->env->from);
draw_envelope_addr (HDR_TO, msg->env->to);
draw_envelope_addr (HDR_CC, msg->env->cc);

View file

@ -0,0 +1,38 @@
From: Evgeni Golov <sargentd@die-welt.net>
Date: Wed, 5 Mar 2014 17:46:07 +0100
Subject: sidebar-delimnullwide
SidebarDelim can be NULL and strlen(NULL) is a bad idea, as it will segfault.
Wrap it with NONULL().
While at it, change strlen to mbstowcs for better utf8 support.
Closes: #696145, #663883
Gbp-Pq: Topic mutt-patched
---
sidebar.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sidebar.c b/sidebar.c
index 51a25ca..c3ea338 100644
--- a/sidebar.c
+++ b/sidebar.c
@@ -88,7 +88,7 @@ char *make_sidebar_entry(char *box, int size, int new, int flagged)
int box_len, box_bytes;
int int_len;
int right_offset = 0;
- int delim_len = strlen(SidebarDelim);
+ int delim_len = mbstowcs(NULL, NONULL(SidebarDelim), 0);
static char *entry;
right_width = left_width = 0;
@@ -178,7 +178,7 @@ int draw_sidebar(int menu) {
#ifndef USE_SLANG_CURSES
attr_t attrs;
#endif
- short delim_len = strlen(SidebarDelim);
+ short delim_len = mbstowcs(NULL, NONULL(SidebarDelim), 0);
short color_pair;
static bool initialized = false;

View file

@ -0,0 +1,98 @@
From: Fabian Groffen <grobian@gentoo.org>
Date: Tue, 4 Mar 2014 21:12:15 +0100
Subject: sidebar-dotpathsep
Make path separators for sidebar folders configurable.
When using IMAP, a '.' is often used as path separator, hence make the
path separators configurable through sidebar_delim_chars variable.
It defaults to "/." to work for both mboxes as well as IMAP folders. It
can be set to only "/" or "." or whichever character desired as needed.
Gbp-Pq: Topic mutt-patched
---
globals.h | 1 +
init.h | 8 ++++++++
sidebar.c | 31 ++++++++++++++++++++++++-------
3 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/globals.h b/globals.h
index 004c795..602f932 100644
--- a/globals.h
+++ b/globals.h
@@ -119,6 +119,7 @@ WHERE char *SendCharset;
WHERE char *Sendmail;
WHERE char *Shell;
WHERE char *SidebarDelim;
+WHERE char *SidebarDelimChars INITVAL (NULL);
WHERE char *Signature;
WHERE char *SimpleSearch;
#if USE_SMTP
diff --git a/init.h b/init.h
index c664e5f..166671b 100644
--- a/init.h
+++ b/init.h
@@ -2051,6 +2051,14 @@ struct option_t MuttVars[] = {
** .pp
** The width of the sidebar.
*/
+ { "sidebar_delim_chars", DT_STR, R_NONE, UL &SidebarDelimChars, UL "/." },
+ /*
+ ** .pp
+ ** This contains the list of characters which you would like to treat
+ ** as folder separators for displaying paths in the sidebar. If
+ ** you're not using IMAP folders, you probably prefer setting this to "/"
+ ** alone.
+ */
{ "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
/*
** .pp
diff --git a/sidebar.c b/sidebar.c
index 6098c2a..4356ffc 100644
--- a/sidebar.c
+++ b/sidebar.c
@@ -249,20 +249,37 @@ int draw_sidebar(int menu) {
// calculate depth of current folder and generate its display name with indented spaces
int sidebar_folder_depth = 0;
char *sidebar_folder_name;
- sidebar_folder_name = basename(tmp->path);
+ int i;
+ sidebar_folder_name = tmp->path;
+ /* disregard a trailing separator, so strlen() - 2
+ * https://bugs.gentoo.org/show_bug.cgi?id=373197#c16 */
+ for (i = strlen(sidebar_folder_name) - 2; i >= 0; i--) {
+ if (SidebarDelimChars &&
+ strchr(SidebarDelimChars, sidebar_folder_name[i]))
+ {
+ sidebar_folder_name += i + 1;
+ break;
+ }
+ }
if ( maildir_is_prefix ) {
char *tmp_folder_name;
- int i;
+ int lastsep = 0;
tmp_folder_name = tmp->path + strlen(Maildir);
- for (i = 0; i < strlen(tmp->path) - strlen(Maildir); i++) {
- if (tmp_folder_name[i] == '/') sidebar_folder_depth++;
- }
+ for (i = 0; i < strlen(tmp_folder_name) - 1; i++) {
+ if (SidebarDelimChars &&
+ strchr(SidebarDelimChars, tmp_folder_name[i]))
+ {
+ sidebar_folder_depth++;
+ lastsep = i + 1;
+ }
+ }
if (sidebar_folder_depth > 0) {
- sidebar_folder_name = malloc(strlen(basename(tmp->path)) + sidebar_folder_depth + 1);
+ tmp_folder_name += lastsep; /* basename */
+ sidebar_folder_name = malloc(strlen(tmp_folder_name) + sidebar_folder_depth + 1);
for (i=0; i < sidebar_folder_depth; i++)
sidebar_folder_name[i]=' ';
sidebar_folder_name[i]=0;
- strncat(sidebar_folder_name, basename(tmp->path), strlen(basename(tmp->path)) + sidebar_folder_depth);
+ strncat(sidebar_folder_name, tmp_folder_name, strlen(tmp_folder_name) + sidebar_folder_depth);
}
}
printw( "%.*s", SidebarWidth - delim_len + 1,

View file

@ -0,0 +1,97 @@
From 355399bde98203af59d20821f9e840fc056bd383 Mon Sep 17 00:00:00 2001
From: Julius Haertl <jus@bitgrid.net>
Date: Tue, 9 Sep 2014 22:31:49 +0200
Subject: Patch for sidebar iteration functionality
sidebar-new will move the selected folder to the next with new messages.
If the end is reached, it will start at the top.
Useful macros would be:
macro index <esc>a "<sidebar-new><sidebar-open>"
macro pager <esc>a "<exit><sidebar-new><sidebar-open>"
---
OPS | 1 +
curs_main.c | 1 +
functions.h | 2 ++
pager.c | 1 +
sidebar.c | 10 ++++++++++
5 files changed, 15 insertions(+)
diff --git a/OPS b/OPS
index 1ed9c96..3ffb82a 100644
--- a/OPS
+++ b/OPS
@@ -187,3 +187,4 @@ OP_SIDEBAR_PREV "go to previous mailbox"
OP_SIDEBAR_OPEN "open hilighted mailbox"
OP_SIDEBAR_NEXT_NEW "go down to next mailbox with new mail"
OP_SIDEBAR_PREV_NEW "go to previous mailbox with new mail"
+OP_SIDEBAR_NEW "iterate though mailboxes with new mail"
diff --git a/curs_main.c b/curs_main.c
index acb106d..2e35f90 100644
--- a/curs_main.c
+++ b/curs_main.c
@@ -2328,6 +2328,7 @@ int mutt_index_menu (void)
case OP_SIDEBAR_PREV:
case OP_SIDEBAR_NEXT_NEW:
case OP_SIDEBAR_PREV_NEW:
+ case OP_SIDEBAR_NEW:
scroll_sidebar(op, menu->menu);
break;
default:
diff --git a/functions.h b/functions.h
index 363b4d5..1485080 100644
--- a/functions.h
+++ b/functions.h
@@ -176,6 +176,7 @@ const struct binding_t OpMain[] = { /* map: index */
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
{ "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
{ "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
+ { "sidebar-new", OP_SIDEBAR_NEW, NULL },
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
{ NULL, 0, NULL }
};
@@ -287,6 +288,7 @@ const struct binding_t OpPager[] = { /* map: pager */
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
{ "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
{ "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
+ { "sidebar-new", OP_SIDEBAR_NEW, NULL },
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
{ NULL, 0, NULL }
};
diff --git a/pager.c b/pager.c
index 8d64fe1..696e55c 100644
--- a/pager.c
+++ b/pager.c
@@ -2791,6 +2791,7 @@ search_next:
case OP_SIDEBAR_PREV:
case OP_SIDEBAR_NEXT_NEW:
case OP_SIDEBAR_PREV_NEW:
+ case OP_SIDEBAR_NEW:
scroll_sidebar(ch, MENU_PAGER);
break;
diff --git a/sidebar.c b/sidebar.c
index c3ea338..eb8ecd2 100644
--- a/sidebar.c
+++ b/sidebar.c
@@ -429,6 +429,16 @@ void scroll_sidebar(int op, int menu)
CurBuffy = CurBuffy->next;
}
break;
+ case OP_SIDEBAR_NEW:
+ if ( (tmp = exist_next_new()) == NULL)
+ tmp = TopBuffy;
+ if ( tmp->msg_unread == 0 ) {
+ CurBuffy = tmp;
+ tmp = exist_next_new();
+ }
+ if ( tmp != NULL )
+ CurBuffy = tmp;
+ break;
default:
return;
}
--
2.6.0.rc0.2.g7662973.dirty

View file

@ -0,0 +1,198 @@
From: Steve Kemp <steve@steve.org.uk>
Date: Tue, 4 Mar 2014 22:07:06 +0100
Subject: sidebar-newonly
patches written by Steve Kemp, it adds two new functionalities to the sidebar,
so only the mailbox with new messages will be shown (and/or) selected
See Debian bug http://bugs.debian.org/532510
Gbp-Pq: Topic mutt-patched
---
OPS | 2 ++
curs_main.c | 2 ++
functions.h | 4 ++++
init.h | 5 +++++
mutt.h | 2 ++
pager.c | 2 ++
sidebar.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
7 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/OPS b/OPS
index b036db9..1ed9c96 100644
--- a/OPS
+++ b/OPS
@@ -185,3 +185,5 @@ OP_SIDEBAR_SCROLL_DOWN "scroll the mailbox pane down 1 page"
OP_SIDEBAR_NEXT "go down to next mailbox"
OP_SIDEBAR_PREV "go to previous mailbox"
OP_SIDEBAR_OPEN "open hilighted mailbox"
+OP_SIDEBAR_NEXT_NEW "go down to next mailbox with new mail"
+OP_SIDEBAR_PREV_NEW "go to previous mailbox with new mail"
diff --git a/curs_main.c b/curs_main.c
index ea530a6..acb106d 100644
--- a/curs_main.c
+++ b/curs_main.c
@@ -2326,6 +2326,8 @@ int mutt_index_menu (void)
case OP_SIDEBAR_SCROLL_DOWN:
case OP_SIDEBAR_NEXT:
case OP_SIDEBAR_PREV:
+ case OP_SIDEBAR_NEXT_NEW:
+ case OP_SIDEBAR_PREV_NEW:
scroll_sidebar(op, menu->menu);
break;
default:
diff --git a/functions.h b/functions.h
index ef8937a..363b4d5 100644
--- a/functions.h
+++ b/functions.h
@@ -174,6 +174,8 @@ const struct binding_t OpMain[] = { /* map: index */
{ "sidebar-scroll-down", OP_SIDEBAR_SCROLL_DOWN, NULL },
{ "sidebar-next", OP_SIDEBAR_NEXT, NULL },
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
+ { "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
+ { "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
{ NULL, 0, NULL }
};
@@ -283,6 +285,8 @@ const struct binding_t OpPager[] = { /* map: pager */
{ "sidebar-scroll-down", OP_SIDEBAR_SCROLL_DOWN, NULL },
{ "sidebar-next", OP_SIDEBAR_NEXT, NULL },
{ "sidebar-prev", OP_SIDEBAR_PREV, NULL },
+ { "sidebar-next-new", OP_SIDEBAR_NEXT_NEW, NULL},
+ { "sidebar-prev-new", OP_SIDEBAR_PREV_NEW, NULL},
{ "sidebar-open", OP_SIDEBAR_OPEN, NULL },
{ NULL, 0, NULL }
};
diff --git a/init.h b/init.h
index 166671b..a5d4238 100644
--- a/init.h
+++ b/init.h
@@ -2059,6 +2059,11 @@ struct option_t MuttVars[] = {
** you're not using IMAP folders, you probably prefer setting this to "/"
** alone.
*/
+ {"sidebar_newmail_only", DT_BOOL, R_BOTH, OPTSIDEBARNEWMAILONLY, 0 },
+ /*
+ ** .pp
+ ** Show only new mail in the sidebar.
+ */
{ "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
/*
** .pp
diff --git a/mutt.h b/mutt.h
index 5f25406..d73e514 100644
--- a/mutt.h
+++ b/mutt.h
@@ -529,6 +529,8 @@ enum
OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */
OPTUNBUFFEREDINPUT, /* (pseudo) don't use key buffer */
+ OPTSIDEBARNEWMAILONLY,
+
OPTMAX
};
diff --git a/pager.c b/pager.c
index 5cfcb75..8d64fe1 100644
--- a/pager.c
+++ b/pager.c
@@ -2789,6 +2789,8 @@ search_next:
case OP_SIDEBAR_SCROLL_DOWN:
case OP_SIDEBAR_NEXT:
case OP_SIDEBAR_PREV:
+ case OP_SIDEBAR_NEXT_NEW:
+ case OP_SIDEBAR_PREV_NEW:
scroll_sidebar(ch, MENU_PAGER);
break;
diff --git a/sidebar.c b/sidebar.c
index 8f58f85..51a25ca 100644
--- a/sidebar.c
+++ b/sidebar.c
@@ -269,8 +269,21 @@ int draw_sidebar(int menu) {
SETCOLOR(MT_COLOR_NEW);
else if ( tmp->msg_flagged > 0 )
SETCOLOR(MT_COLOR_FLAGGED);
- else
- SETCOLOR(MT_COLOR_NORMAL);
+ else {
+ /* make sure the path is either:
+ 1. Containing new mail.
+ 2. The inbox.
+ 3. The current box.
+ */
+ if ((option (OPTSIDEBARNEWMAILONLY)) &&
+ ( (tmp->msg_unread <= 0) &&
+ ( tmp != Incoming ) &&
+ Context &&
+ ( strcmp( tmp->path, Context->path ) != 0 ) ) )
+ continue;
+ else
+ SETCOLOR(MT_COLOR_NORMAL);
+ }
move( lines, 0 );
if ( Context && !strcmp( tmp->path, Context->path ) ) {
@@ -336,6 +349,29 @@ int draw_sidebar(int menu) {
return 0;
}
+BUFFY * exist_next_new()
+{
+ BUFFY *tmp = CurBuffy;
+ if(tmp == NULL) return NULL;
+ while (tmp->next != NULL)
+ {
+ tmp = tmp->next;
+ if(tmp->msg_unread) return tmp;
+ }
+ return NULL;
+}
+
+BUFFY * exist_prev_new()
+{
+ BUFFY *tmp = CurBuffy;
+ if(tmp == NULL) return NULL;
+ while (tmp->prev != NULL)
+ {
+ tmp = tmp->prev;
+ if(tmp->msg_unread) return tmp;
+ }
+ return NULL;
+}
void set_buffystats(CONTEXT* Context)
{
@@ -352,18 +388,33 @@ void set_buffystats(CONTEXT* Context)
void scroll_sidebar(int op, int menu)
{
+ BUFFY *tmp;
if(!SidebarWidth) return;
if(!CurBuffy) return;
switch (op) {
case OP_SIDEBAR_NEXT:
+ if (!option (OPTSIDEBARNEWMAILONLY)) {
if ( CurBuffy->next == NULL ) return;
CurBuffy = CurBuffy->next;
break;
+ }
+ case OP_SIDEBAR_NEXT_NEW:
+ if ( (tmp = exist_next_new()) == NULL)
+ return;
+ else CurBuffy = tmp;
+ break;
case OP_SIDEBAR_PREV:
+ if (!option (OPTSIDEBARNEWMAILONLY)) {
if ( CurBuffy->prev == NULL ) return;
CurBuffy = CurBuffy->prev;
break;
+ }
+ case OP_SIDEBAR_PREV_NEW:
+ if ( (tmp = exist_prev_new()) == NULL)
+ return;
+ else CurBuffy = tmp;
+ break;
case OP_SIDEBAR_SCROLL_UP:
CurBuffy = TopBuffy;
if ( CurBuffy != Incoming ) {

View file

@ -0,0 +1,132 @@
From: Antonio Radici <antonio@debian.org>
Date: Tue, 4 Mar 2014 15:39:14 +0100
Subject: sidebar-utf8
This patch fixes a problem with utf-8 strings and the sidebar,
it rewrites entirely make_sidebar_entry so it also fixes some
segfaults due to misallocations and overflows.
See:
http://bugs.debian.org/584581
http://bugs.debian.org/603287
Gbp-Pq: Topic mutt-patched
---
sidebar.c | 97 +++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 67 insertions(+), 30 deletions(-)
diff --git a/sidebar.c b/sidebar.c
index 4356ffc..8f58f85 100644
--- a/sidebar.c
+++ b/sidebar.c
@@ -30,6 +30,7 @@
#include <libgen.h>
#include "keymap.h"
#include <stdbool.h>
+#include <wchar.h>
/*BUFFY *CurBuffy = 0;*/
static BUFFY *TopBuffy = 0;
@@ -82,36 +83,72 @@ void calc_boundaries (int menu)
char *make_sidebar_entry(char *box, int size, int new, int flagged)
{
- static char *entry = 0;
- char *c;
- int i = 0;
- int delim_len = strlen(SidebarDelim);
-
- c = realloc(entry, SidebarWidth - delim_len + 2);
- if ( c ) entry = c;
- entry[SidebarWidth - delim_len + 1] = 0;
- for (; i < SidebarWidth - delim_len + 1; entry[i++] = ' ' );
- i = strlen(box);
- strncpy( entry, box, i < (SidebarWidth - delim_len + 1) ? i : (SidebarWidth - delim_len + 1) );
-
- if (size == -1)
- sprintf(entry + SidebarWidth - delim_len - 3, "?");
- else if ( new ) {
- if (flagged > 0) {
- sprintf(
- entry + SidebarWidth - delim_len - 5 - quick_log10(size) - quick_log10(new) - quick_log10(flagged),
- "% d(%d)[%d]", size, new, flagged);
- } else {
- sprintf(
- entry + SidebarWidth - delim_len - 3 - quick_log10(size) - quick_log10(new),
- "% d(%d)", size, new);
- }
- } else if (flagged > 0) {
- sprintf( entry + SidebarWidth - delim_len - 3 - quick_log10(size) - quick_log10(flagged), "% d[%d]", size, flagged);
- } else {
- sprintf( entry + SidebarWidth - delim_len - 1 - quick_log10(size), "% d", size);
- }
- return entry;
+ char int_store[20]; // up to 64 bits integers
+ int right_width, left_width;
+ int box_len, box_bytes;
+ int int_len;
+ int right_offset = 0;
+ int delim_len = strlen(SidebarDelim);
+ static char *entry;
+
+ right_width = left_width = 0;
+ box_len = box_bytes = 0;
+
+ // allocate an entry big enough to contain SidebarWidth wide chars
+ entry = malloc((SidebarWidth*4)+1); // TODO: error check
+
+ // determine the right space (i.e.: how big are the numbers that we want to print)
+ if ( size > 0 ) {
+ int_len = snprintf(int_store, sizeof(int_store), "%d", size);
+ right_width += int_len;
+ } else {
+ right_width = 1; // to represent 0
+ }
+ if ( new > 0 ) {
+ int_len = snprintf(int_store, sizeof(int_store), "%d", new);
+ right_width += int_len + 2; // 2 is for ()
+ }
+ if ( flagged > 0 ) {
+ int_len = snprintf(int_store, sizeof(int_store), "%d", flagged);
+ right_width += int_len + 2; // 2 is for []
+ }
+
+ // determine how much space we have for *box and its padding (if any)
+ left_width = SidebarWidth - right_width - 1 - delim_len; // 1 is for the space
+ //fprintf(stdout, "left_width: %d right_width: %d\n", left_width, right_width);
+ // right side overflow case
+ if ( left_width <= 0 ) {
+ snprintf(entry, SidebarWidth*4, "%-*.*s ...", SidebarWidth-4-delim_len, SidebarWidth-4-delim_len, box);
+ return entry;
+ }
+ right_width -= delim_len;
+
+ // to support utf-8 chars we need to add enough space padding in case there
+ // are less chars than bytes in *box
+ box_len = mbstowcs(NULL, box, 0);
+ box_bytes = strlen(box);
+ // debug
+ //fprintf(stdout, "box_len: %d box_bytes: %d (diff: %d)\n", box_len, box_bytes, (box_bytes-box_len));
+ // if there is less string than the space we allow, then we will add the
+ // spaces
+ if ( box_len != -1 && box_len < left_width ) {
+ left_width += (box_bytes - box_len);
+ }
+ // otherwise sprintf will truncate the string for us (therefore, no else case)
+
+ // print the sidebar entry (without new and flagged messages, at the moment)
+ //fprintf(stdout, "left_width: %d right_width: %d\n", left_width, right_width);
+ right_offset = snprintf(entry, SidebarWidth*4, "%-*.*s %d", left_width, left_width, box, size);
+
+ // then pad new and flagged messages if any
+ if ( new > 0 ) {
+ right_offset += snprintf(entry+right_offset, SidebarWidth*4-right_offset, "(%d)", new);
+ }
+ if ( flagged > 0 ) {
+ right_offset += snprintf(entry+right_offset, SidebarWidth*4-right_offset, "[%d]", flagged);
+ }
+
+ return entry;
}
void set_curbuffy(char buf[LONG_STRING])

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,316 @@
From: Cedric Duval <cedricduval@free.fr>
Date: Thu, 27 Feb 2014 12:27:41 +0100
Subject: trash-folder
With this patch, if the trash variable is set to a path (unset by default), the
deleted mails will be moved to a trash folder instead of being irremediably
purged when syncing the mailbox.
For instance, set trash="~/Mail/trash" will cause every deleted mail to go to
this folder.
Note that the append to the trash folder doesn't occur until the resync is
done. This allows you to change your mind and undo deletes, and thus the moves
to the trash folder are unnecessary.
Notes
* You might also want to have a look at the purge message feature below
which is related to this patch.
* IMAP is now supported. To retain the previous behavior, add this to your
muttrc:
folder-hook ^imap:// 'unset trash'
FAQ
Every once in a while, someone asks what are the advantages of this patch over
a macro based solution. Here's an attempt to answer this question:
* The folder history doesn't clutter up with unwanted trash entries.
* Delayed move to the trash allows to change one's mind.
* No need to treat the case of "normal folders" and trash folders
separately with folder-hooks, and to create two sets of macros (one for
the index, one for the pager).
* Works not only with delete-message, but also with every deletion
functions like delete-pattern, delete-thread or delete-subthread.
To sum up, it's more integrated and transparent to the user.
* Patch last synced with upstream:
- Date: 2007-02-15
- File: http://cedricduval.free.fr/mutt/patches/download/patch-1.5.5.1.cd.trash_folder.3.4
* Changes made:
- Updated to 1.5.13:
- structure of _mutt_save_message changed (commands.c)
- context of option (OPTCONFIRMAPPEND) changed (muttlib.c)
- Fixed indentation of "appended" in mutt.h.
Signed-off-by: Matteo F. Vescovi <mfvescovi@gmail.com>
Gbp-Pq: Topic features
---
commands.c | 1 +
flags.c | 19 +++++++++++++++++-
globals.h | 1 +
imap/message.c | 2 ++
init.h | 10 ++++++++++
mutt.h | 3 +++
muttlib.c | 4 +++-
mx.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
postpone.c | 3 +++
9 files changed, 103 insertions(+), 2 deletions(-)
diff --git a/commands.c b/commands.c
index 5dbd100..7fd014b 100644
--- a/commands.c
+++ b/commands.c
@@ -720,6 +720,7 @@ int _mutt_save_message (HEADER *h, CONTEXT *ctx, int delete, int decode, int dec
if (option (OPTDELETEUNTAG))
mutt_set_flag (Context, h, M_TAG, 0);
}
+ mutt_set_flag (Context, h, M_APPENDED, 1);
return 0;
}
diff --git a/flags.c b/flags.c
index f0f3d81..dfa6a50 100644
--- a/flags.c
+++ b/flags.c
@@ -65,7 +65,13 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
{
h->deleted = 0;
update = 1;
- if (upd_ctx) ctx->deleted--;
+ if (upd_ctx)
+ {
+ ctx->deleted--;
+ if (h->appended)
+ ctx->appended--;
+ }
+ h->appended = 0; /* when undeleting, also reset the appended flag */
#ifdef USE_IMAP
/* see my comment above */
if (ctx->magic == M_IMAP)
@@ -87,6 +93,17 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
}
break;
+ case M_APPENDED:
+ if (bf)
+ {
+ if (!h->appended)
+ {
+ h->appended = 1;
+ if (upd_ctx) ctx->appended++;
+ }
+ }
+ break;
+
case M_NEW:
if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
diff --git a/globals.h b/globals.h
index e77030c..6a1b8da 100644
--- a/globals.h
+++ b/globals.h
@@ -144,6 +144,7 @@ WHERE char *Tochars;
WHERE char *TSStatusFormat;
WHERE char *TSIconFormat;
WHERE short TSSupported;
+WHERE char *TrashPath;
WHERE char *Username;
WHERE char *Visual;
diff --git a/imap/message.c b/imap/message.c
index 3877381..039fda6 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -884,6 +884,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
if (ctx->hdrs[n]->tagged)
{
mutt_set_flag (ctx, ctx->hdrs[n], M_DELETE, 1);
+ mutt_set_flag (ctx, ctx->hdrs[n], M_APPENDED, 1);
if (option (OPTDELETEUNTAG))
mutt_set_flag (ctx, ctx->hdrs[n], M_TAG, 0);
}
@@ -891,6 +892,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
else
{
mutt_set_flag (ctx, h, M_DELETE, 1);
+ mutt_set_flag (ctx, h, M_APPENDED, 1);
if (option (OPTDELETEUNTAG))
mutt_set_flag (ctx, h, M_TAG, 0);
}
diff --git a/init.h b/init.h
index 6b49341..d3206f9 100644
--- a/init.h
+++ b/init.h
@@ -3341,6 +3341,16 @@ struct option_t MuttVars[] = {
** provided that ``$$ts_enabled'' has been set. This string is identical in
** formatting to the one used by ``$$status_format''.
*/
+ { "trash", DT_PATH, R_NONE, UL &TrashPath, 0 },
+ /*
+ ** .pp
+ ** If set, this variable specifies the path of the trash folder where the
+ ** mails marked for deletion will be moved, instead of being irremediably
+ ** purged.
+ ** .pp
+ ** NOTE: When you delete a message in the trash folder, it is really
+ ** deleted, so that you have a way to clean the trash.
+ */
#ifdef USE_SOCKET
{ "tunnel", DT_STR, R_NONE, UL &Tunnel, UL 0 },
/*
diff --git a/mutt.h b/mutt.h
index f8565fa..29bb6c2 100644
--- a/mutt.h
+++ b/mutt.h
@@ -185,6 +185,7 @@ enum
M_DELETE,
M_UNDELETE,
M_DELETED,
+ M_APPENDED,
M_FLAG,
M_TAG,
M_UNTAG,
@@ -713,6 +714,7 @@ typedef struct header
unsigned int mime : 1; /* has a MIME-Version header? */
unsigned int flagged : 1; /* marked important? */
unsigned int tagged : 1;
+ unsigned int appended : 1; /* has been saved */
unsigned int deleted : 1;
unsigned int changed : 1;
unsigned int attach_del : 1; /* has an attachment marked for deletion */
@@ -885,6 +887,7 @@ typedef struct _context
int new; /* how many new messages? */
int unread; /* how many unread messages? */
int deleted; /* how many deleted messages */
+ int appended; /* how many saved messages? */
int flagged; /* how many flagged messages */
int msgnotreadyet; /* which msg "new" in pager, -1 if none */
diff --git a/muttlib.c b/muttlib.c
index 02067cc..0fd9766 100644
--- a/muttlib.c
+++ b/muttlib.c
@@ -1505,7 +1505,9 @@ int mutt_save_confirm (const char *s, struct stat *st)
if (magic > 0 && !mx_access (s, W_OK))
{
- if (option (OPTCONFIRMAPPEND))
+ if (option (OPTCONFIRMAPPEND) &&
+ (!TrashPath || (mutt_strcmp (s, TrashPath) != 0)))
+ /* if we're appending to the trash, there's no point in asking */
{
snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s);
if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
diff --git a/mx.c b/mx.c
index 4c5cb07..c0a6d30 100644
--- a/mx.c
+++ b/mx.c
@@ -776,6 +776,53 @@ static int sync_mailbox (CONTEXT *ctx, int *index_hint)
return rc;
}
+/* move deleted mails to the trash folder */
+static int trash_append (CONTEXT *ctx)
+{
+ CONTEXT *ctx_trash;
+ int i = 0;
+ struct stat st, stc;
+
+ if (!TrashPath || !ctx->deleted ||
+ (ctx->magic == M_MAILDIR && option (OPTMAILDIRTRASH)))
+ return 0;
+
+ for (;i < ctx->msgcount && (!ctx->hdrs[i]->deleted ||
+ ctx->hdrs[i]->appended); i++);
+ if (i == ctx->msgcount)
+ return 0; /* nothing to be done */
+
+ if (mutt_save_confirm (TrashPath, &st) != 0)
+ {
+ mutt_error _("message(s) not deleted");
+ return -1;
+ }
+
+ if (lstat (ctx->path, &stc) == 0 && stc.st_ino == st.st_ino
+ && stc.st_dev == st.st_dev && stc.st_rdev == st.st_rdev)
+ return 0; /* we are in the trash folder: simple sync */
+
+ if ((ctx_trash = mx_open_mailbox (TrashPath, M_APPEND, NULL)) != NULL)
+ {
+ for (i = 0 ; i < ctx->msgcount ; i++)
+ if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->appended
+ && mutt_append_message (ctx_trash, ctx, ctx->hdrs[i], 0, 0) == -1)
+ {
+ mx_close_mailbox (ctx_trash, NULL);
+ return -1;
+ }
+
+ mx_close_mailbox (ctx_trash, NULL);
+ }
+ else
+ {
+ mutt_error _("Can't open trash folder");
+ return -1;
+ }
+
+ return 0;
+}
+
/* save changes and close mailbox */
int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
{
@@ -912,6 +959,7 @@ int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
if (mutt_append_message (&f, ctx, ctx->hdrs[i], 0, CH_UPDATE_LEN) == 0)
{
mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, 1);
+ mutt_set_flag (ctx, ctx->hdrs[i], M_APPENDED, 1);
}
else
{
@@ -936,6 +984,14 @@ int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
return 0;
}
+ /* copy mails to the trash before expunging */
+ if (purge && ctx->deleted && mutt_strcmp(ctx->path, TrashPath))
+ if (trash_append (ctx) != 0)
+ {
+ ctx->closing = 0;
+ return -1;
+ }
+
#ifdef USE_IMAP
/* allow IMAP to preserve the deleted flag across sessions */
if (ctx->magic == M_IMAP)
@@ -1133,6 +1189,12 @@ int mx_sync_mailbox (CONTEXT *ctx, int *index_hint)
msgcount = ctx->msgcount;
deleted = ctx->deleted;
+ if (purge && ctx->deleted && mutt_strcmp(ctx->path, TrashPath))
+ {
+ if (trash_append (ctx) == -1)
+ return -1;
+ }
+
#ifdef USE_IMAP
if (ctx->magic == M_IMAP)
rc = imap_sync_mailbox (ctx, purge, index_hint);
diff --git a/postpone.c b/postpone.c
index a703161..7a4cbb1 100644
--- a/postpone.c
+++ b/postpone.c
@@ -277,6 +277,9 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, char *fcc, size
/* finished with this message, so delete it. */
mutt_set_flag (PostContext, h, M_DELETE, 1);
+ /* and consider it saved, so that it won't be moved to the trash folder */
+ mutt_set_flag (PostContext, h, M_APPENDED, 1);
+
/* update the count for the status display */
PostCount = PostContext->msgcount - PostContext->deleted;