]> granicus.if.org Git - neomutt/commitdiff
Rework the "inbox-first" implementation to make code self-explanatory (#356)
authorPietro Cerutti <gahr@gahr.ch>
Sun, 5 Feb 2017 14:22:25 +0000 (14:22 +0000)
committerRichard Russon <rich@flatcap.org>
Sun, 5 Feb 2017 14:22:25 +0000 (14:22 +0000)
Do not sort INBOX before its parent folder

This is achieved by considering /a/b/ and /a/b/c/d as different
subpaths, thus avoiding this situation

/a/b/INBOX
/a/b/

Closes #301

browser.c
lib.c
lib.h
sidebar.c

index 5ab2cbcebe1eaf6d670134548160cc7530e1bbca..24256d0ee5f69b69eeec99cd5696a2ba34b2eaa1 100644 (file)
--- a/browser.c
+++ b/browser.c
@@ -103,11 +103,9 @@ static int browser_compare_subject (const void *a, const void *b)
   struct folder_file *pb = (struct folder_file *) b;
 
   /* inbox should be sorted ahead of its siblings */
-  int common_subpath = mutt_have_common_subpath (pa->name, pb->name);
-  int r = (common_subpath && mutt_is_inbox (pa->name)) ? -1 :
-          (common_subpath && mutt_is_inbox (pb->name)) ?  1 :
-          mutt_strcoll  (pa->name, pb->name);
-
+  int r = mutt_inbox_cmp (pa->name, pb->name);
+  if (r == 0)
+      r = mutt_strcoll (pa->name, pb->name);
   return ((BrowserSort & SORT_REVERSE) ? -r : r);
 }
 
diff --git a/lib.c b/lib.c
index 299b19dfadb98ed01a1d22f63541a45a2e4acce1..c6b1a1265a808ef50120541703415a985b2a78eb 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -1107,26 +1107,29 @@ int mutt_atol (const char *str, long *dst)
   return 0;
 }
 
-int mutt_is_inbox (const char *path)
-{
-  size_t plen = mutt_strlen (path);
-  return ((plen >= 6) && (mutt_strcasecmp (path + plen - 6, "/inbox") == 0));
-}
-
 /**
- * mutt_have_common_subpath - check whether two paths have a common subpath.
+ * mutt_inbox_cmp - check whether two folders share the same path and one is
+ * an inbox.
+ *
  * @param a First path.
  * @param b Second path.
  *
- * @return 1 if a and b have a common subpath, 0 otherwise
+ * @return -1 if a is INBOX of b, 0 if none is INBOX, 1 if b is INBOX for a
  *
- * This function checks whether two paths (where the path separator is assumed
- * to be '/', have a common subpath. Examples:
+ * This function compares two folder paths. It first looks for the position of
+ * the last common '/' character. If a valid position is found and it's not the
+ * last character in any of the two paths, the remaining parts of the paths are
+ * compared (case insensitively) with the string "INBOX". If one of the two
+ * paths matches, it's reported as being less than the other and the function
+ * returns -1 (a < b) or 1 (a > b). If no paths match the requirements, the two
+ * paths are considered equivalent and this function returns 0.
  *
- * /foo/bar/baz and /foo/hey/you do have a common subpath (/foo/)
- * /apple/banana and /apples/bananas do NOT have a common subpath
+ * Examples:
+ *   mutt_inbox_cmp("/foo/bar",      "/foo/baz") --> 0
+ *   mutt_inbox_cmp("/foo/bar/",     "/foo/bar/inbox") --> 0
+ *   mutt_inbox_cmp("/foo/bar/sent", "/foo/bar/inbox") --> 1
  */
-int mutt_have_common_subpath(const char *a, const char *b)
+int mutt_inbox_cmp (const char *a, const char *b)
 {
   const char *a_end = strrchr (a, '/');
   const char *b_end = strrchr (b, '/');
@@ -1137,14 +1140,26 @@ int mutt_have_common_subpath(const char *a, const char *b)
 
   /* If neither path contains a '/' */
   if (!a_end)
-    return 1;
+    return 0;
 
-  /* Compare the paths */
+  /* Compare the subpaths */
   size_t a_len = a_end - a;
   size_t b_len = b_end - b;
   size_t min = MIN(a_len, b_len);
-  return (a[min] == '/') && (b[min] == '/') &&
-         (mutt_strncasecmp(a, b, min) == 0);
+  int same = (a[min] == '/') && (b[min] == '/') &&
+             (a[min+1] != '\0') && (b[min+1] != '\0') &&
+             (mutt_strncasecmp(a, b, min) == 0);
+
+  if (!same)
+      return 0;
+
+  if (mutt_strcasecmp(&a[min+1], "inbox") == 0)
+      return -1;
+
+  if (mutt_strcasecmp(&b[min+1], "inbox") == 0)
+      return 1;
+
+  return 0;
 }
 
 char * strfcpy (char *dest, const char *src, size_t dlen)
diff --git a/lib.h b/lib.h
index 97e873a3ec60ca8ff3379784b4bf73f69b109756..ef5e4f3bd7bc2f5b0c7c3267b0412c54bd3e78dd 100644 (file)
--- a/lib.h
+++ b/lib.h
@@ -225,8 +225,7 @@ void mutt_str_adjust (char **p);
 void mutt_unlink (const char *);
 void safe_free (void *);
 void safe_realloc (void *, size_t);
-int  mutt_is_inbox (const char *path);
-int  mutt_have_common_subpath (const char *a, const char *b);
+int  mutt_inbox_cmp (const char *a, const char *b);
 
 const char *mutt_strsysexit(int e);
 #endif
index 4c0baed7fd670096d4ae20dd358db7fe383c4849..9c7bd852b3146fb9a3602ab3e1d23f434a0a715b 100644 (file)
--- a/sidebar.c
+++ b/sidebar.c
@@ -321,10 +321,9 @@ static int cb_qsort_sbe (const void *a, const void *b)
       break;
     case SORT_PATH:
     {
-      int common_subpath = mutt_have_common_subpath (b1->path, b2->path);
-      result = (common_subpath && mutt_is_inbox (b1->path)) ? -1 :
-               (common_subpath && mutt_is_inbox (b2->path)) ?  1 :
-               mutt_strcoll (b1->path, b2->path);           
+      result = mutt_inbox_cmp (b1->path, b2->path);
+      if (result == 0)
+        result = mutt_strcoll (b1->path, b2->path);
       break;
     }
   }