From a6f91bc9c890581cff189e143d86e656cab6d2dc Mon Sep 17 00:00:00 2001 From: Austin Ray Date: Wed, 8 Jul 2020 17:17:59 -0400 Subject: [PATCH] fix(sidebar): abbreviate/shorten what user sees If a user opted to display a name, perform the sidebar shorten, abbreviation, and indentation on the name, not the path. Otherwise, sidebar may render names incorrectly due to operation being calculated on the path. Notmuch users are more susceptible since queries often contain file paths or other characters such periods. If a user wants to display a name but operate under a folder hierarchy, they must represent that hierarchy in the name. --- sidebar/private.h | 4 ++- sidebar/sidebar.c | 69 +++++++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/sidebar/private.h b/sidebar/private.h index 94ba88498b..fadcada9ee 100644 --- a/sidebar/private.h +++ b/sidebar/private.h @@ -36,7 +36,9 @@ extern struct ListHead SidebarWhitelist; struct SbEntry { char box[256]; ///< Mailbox path (possibly abbreviated) - int depth; ///< Indentation depth + char name[256]; ///< Mailbox name (possibly abbreviated) + int depth; ///< Indentation depth for path + int name_depth; ///< Indentation for name struct Mailbox *mailbox; ///< Mailbox this represents bool is_hidden; ///< Don't show, e.g. $sidebar_new_mail_only enum ColorId color; ///< Colour to use diff --git a/sidebar/sidebar.c b/sidebar/sidebar.c index b729af0740..8cb8587d13 100644 --- a/sidebar/sidebar.c +++ b/sidebar/sidebar.c @@ -57,10 +57,10 @@ struct ListHead SidebarWhitelist = STAILQ_HEAD_INITIALIZER(SidebarWhitelist); // * @param sbe Sidebar entry * @retval Number of bytes written */ -static size_t add_indent(char *buf, size_t buflen, const struct SbEntry *sbe) +static size_t add_indent(char *buf, size_t buflen, const int depth) { size_t res = 0; - for (int i = 0; i < sbe->depth; i++) + for (int i = 0; i < depth; i++) { res += mutt_str_copy(buf + res, C_SidebarIndentString, buflen - res); } @@ -114,9 +114,10 @@ static const char *sidebar_format_str(char *buf, size_t buflen, size_t col, int case 'D': { char indented[256]; - size_t offset = add_indent(indented, sizeof(indented), sbe); + int depth = (op == 'D' && sbe->mailbox->name) ? sbe->name_depth : sbe->depth; + size_t offset = add_indent(indented, sizeof(indented), depth); snprintf(indented + offset, sizeof(indented) - offset, "%s", - ((op == 'D') && sbe->mailbox->name) ? sbe->mailbox->name : sbe->box); + ((op == 'D') && sbe->mailbox->name) ? sbe->name : sbe->box); mutt_format_s(buf, buflen, prec, indented); break; @@ -795,6 +796,37 @@ static int calc_path_depth(const char *mbox, const char *delims, const char **la return depth; } +static const char *shorten_abbreviate(struct Mailbox *m, const char *name_or_path, int *depth) +{ + // Try to abbreviate the full path + const char *abbr = abbrev_folder(name_or_path, C_Folder, m->type); + if (!abbr) + abbr = abbrev_url(name_or_path, m->type); + const char *shortened = abbr ? abbr : name_or_path; + + /* Compute the depth */ + const char *last_part = abbr; + *depth = calc_path_depth(abbr, C_SidebarDelimChars, &last_part); + if (!C_SidebarFolderIndent) + *depth = 0; + + const bool short_is_abbr = (shortened == abbr); + if (C_SidebarShortPath) + { + shortened = last_part; + } + + // Don't indent if we were unable to create an abbreviation. + // Otherwise, the full path will be indent, and it looks unusual. + if (C_SidebarFolderIndent && short_is_abbr) + { + if (C_SidebarComponentDepth > 0) + *depth -= C_SidebarComponentDepth; + } + + return shortened; +} + /** * draw_sidebar - Write out a list of mailboxes, in a panel * @param wdata Sidebar data @@ -877,34 +909,13 @@ static void draw_sidebar(struct SidebarWindowData *wdata, struct MuttWindow *win } const char *path = mailbox_path(m); + const char *name = m->name; - // Try to abbreviate the full path - const char *abbr = abbrev_folder(path, C_Folder, m->type); - if (!abbr) - abbr = abbrev_url(path, m->type); - const char *short_path = abbr ? abbr : path; - - /* Compute the depth */ - const char *last_part = abbr; - entry->depth = calc_path_depth(abbr, C_SidebarDelimChars, &last_part); - - const bool short_path_is_abbr = (short_path == abbr); - if (C_SidebarShortPath) - { - short_path = last_part; - } - - // Don't indent if we were unable to create an abbreviation. - // Otherwise, the full path will be indent, and it looks unusual. - if (C_SidebarFolderIndent && short_path_is_abbr) - { - if (C_SidebarComponentDepth > 0) - entry->depth -= C_SidebarComponentDepth; - } - else if (!C_SidebarFolderIndent) - entry->depth = 0; + const char *short_path = shorten_abbreviate(m, path, &entry->depth); + const char *short_name = shorten_abbreviate(m, name, &entry->name_depth); mutt_str_copy(entry->box, short_path, sizeof(entry->box)); + mutt_str_copy(entry->name, short_name, sizeof(entry->name)); char str[256]; make_sidebar_entry(str, sizeof(str), w, entry); mutt_window_printf("%s", str);