]> granicus.if.org Git - mutt/commitdiff
Add $browser_sticky_cursor default set.
authorKevin McCarthy <kevin@8t8.us>
Sun, 8 Sep 2019 17:49:37 +0000 (10:49 -0700)
committerKevin McCarthy <kevin@8t8.us>
Mon, 9 Sep 2019 18:11:49 +0000 (11:11 -0700)
This option attempts to keep the browser cursor on the same mailbox.

It does this by keeping track of the current selected mailbox and
comparing that when regenerating the menu.

Modify imap_mailbox_create() and imap_mailbox_rename() to return the
new mailbox name so it can be automatically selected.

browser.c
imap/browse.c
imap/imap.h
imap/imap_private.h
imap/util.c
init.h
mutt.h

index 56ce75d25a5e9a355932abd7655499b56cb1b8a2..c75406ca6f097361d81e1087c394a5f5a8626999 100644 (file)
--- a/browser.c
+++ b/browser.c
@@ -601,9 +601,10 @@ static void folder_entry (char *s, size_t slen, MUTTMENU *menu, int num)
 }
 
 static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
-                      size_t titlelen, int buffy)
+                      size_t titlelen, int buffy, const char *defaultsel)
 {
   BUFFER *path = NULL;
+  int i;
 
   path = mutt_buffer_pool_get ();
 
@@ -635,6 +636,18 @@ static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
   }
   menu->redraw = REDRAW_FULL;
 
+  if (option (OPTBROWSERSTICKYCURSOR) && defaultsel && *defaultsel)
+  {
+    for (i = 0; i < menu->max; i++)
+    {
+      if (!mutt_strcmp (defaultsel, state->entry[i].full_path))
+      {
+        menu->current = i;
+        break;
+      }
+    }
+  }
+
   mutt_buffer_pool_release (&path);
 }
 
@@ -674,6 +687,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
   BUFFER *prefix = NULL;
   BUFFER *tmp = NULL;
   BUFFER *OldLastDir = NULL;
+  BUFFER *defaultsel = NULL;
   char helpstr[LONG_STRING];
   char title[STRING];
   struct browser_state state;
@@ -691,6 +705,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
   prefix     = mutt_buffer_pool_get ();
   tmp        = mutt_buffer_pool_get ();
   OldLastDir = mutt_buffer_pool_get ();
+  defaultsel  = mutt_buffer_pool_get ();
 
   memset (&state, 0, sizeof (struct browser_state));
 
@@ -757,6 +772,9 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
     else if (!*(mutt_b2s (LastDir)))
       mutt_buffer_strcpy (LastDir, NONULL(Maildir));
 
+    if (Context)
+      mutt_buffer_strcpy (defaultsel, NONULL (Context->path));
+
 #ifdef USE_IMAP
     if (!buffy && mx_is_imap (mutt_b2s (LastDir)))
     {
@@ -803,11 +821,16 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
                                   FolderHelp);
   mutt_push_current_menu (menu);
 
-  init_menu (&state, menu, title, sizeof (title), buffy);
+  init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
 
   FOREVER
   {
-    switch (op = mutt_menuLoop (menu))
+    op = mutt_menuLoop (menu);
+
+    if (state.entrylen)
+      mutt_buffer_strcpy (defaultsel, state.entry[menu->current].full_path);
+
+    switch (op)
     {
       case OP_DESCEND_DIRECTORY:
       case OP_GENERIC_SELECT_ENTRY:
@@ -836,6 +859,13 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
            /* save the old directory */
            mutt_buffer_strcpy (OldLastDir, mutt_b2s (LastDir));
 
+            mutt_buffer_strcpy (defaultsel, mutt_b2s (OldLastDir));
+            if (mutt_buffer_len (defaultsel) && (*(defaultsel->dptr - 1) == '/'))
+            {
+              defaultsel->dptr--;
+              *(defaultsel->dptr) = '\0';
+            }
+
            if (mutt_strcmp (state.entry[menu->current].display_name, "..") == 0)
            {
               size_t lastdirlen = mutt_buffer_len (LastDir);
@@ -921,7 +951,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
               }
            menu->current = 0;
            menu->top = 0;
-           init_menu (&state, menu, title, sizeof (title), buffy);
+           init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
            break;
          }
        }
@@ -992,7 +1022,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
          break;
        }
 
-       if (!imap_mailbox_create (mutt_b2s (LastDir)))
+       if (!imap_mailbox_create (mutt_b2s (LastDir), defaultsel))
        {
          /* TODO: find a way to detect if the new folder would appear in
           *   this window, and insert it without starting over. */
@@ -1004,7 +1034,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
          menu->data = state.entry;
          menu->current = 0;
          menu->top = 0;
-         init_menu (&state, menu, title, sizeof (title), buffy);
+         init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
        }
        /* else leave error on screen */
        break;
@@ -1016,7 +1046,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
        {
          int nentry = menu->current;
 
-         if (imap_mailbox_rename (state.entry[nentry].full_path) >= 0)
+         if (imap_mailbox_rename (state.entry[nentry].full_path, defaultsel) >= 0)
          {
            destroy_state (&state);
            init_state (&state, NULL);
@@ -1026,7 +1056,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
            menu->data = state.entry;
            menu->current = 0;
            menu->top = 0;
-           init_menu (&state, menu, title, sizeof (title), buffy);
+           init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
          }
        }
        break;
@@ -1063,7 +1093,8 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
                       sizeof (struct folder_file));
              state.entrylen--;
              mutt_message _("Mailbox deleted.");
-             init_menu (&state, menu, title, sizeof (title), buffy);
+              mutt_buffer_clear (defaultsel);
+             init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
            }
             else
               mutt_error _("Mailbox deletion failed.");
@@ -1078,6 +1109,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
       case OP_CHANGE_DIRECTORY:
 
        mutt_buffer_strcpy (buf, mutt_b2s (LastDir));
+        mutt_buffer_clear (defaultsel);
 #ifdef USE_IMAP
        if (!state.imap_browse)
 #endif
@@ -1107,7 +1139,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
            menu->data = state.entry;
            menu->current = 0;
            menu->top = 0;
-           init_menu (&state, menu, title, sizeof (title), buffy);
+           init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
          }
          else
 #endif
@@ -1136,7 +1168,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
                }
                menu->current = 0;
                menu->top = 0;
-               init_menu (&state, menu, title, sizeof (title), buffy);
+               init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
              }
              else
                mutt_error (_("%s is not a directory."), mutt_b2s (buf));
@@ -1195,12 +1227,12 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
              imap_browse (mutt_b2s (LastDir), &state);
              browser_sort (&state);
              menu->data = state.entry;
-             init_menu (&state, menu, title, sizeof (title), buffy);
+             init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
            }
            else
 #endif
               if (examine_directory (menu, &state, mutt_b2s (LastDir), NULL) == 0)
-                init_menu (&state, menu, title, sizeof (title), buffy);
+                init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
               else
               {
                 mutt_error _("Error scanning directory.");
@@ -1268,6 +1300,8 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
 
       case OP_TOGGLE_MAILBOXES:
        buffy = 1 - buffy;
+        menu->current = 0;
+        /* fall through */
 
       case OP_CHECK_NEW:
        destroy_state (&state);
@@ -1291,7 +1325,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
 #endif
        else if (examine_directory (menu, &state, mutt_b2s (LastDir), mutt_b2s (prefix)) == -1)
          goto bail;
-       init_menu (&state, menu, title, sizeof (title), buffy);
+       init_menu (&state, menu, title, sizeof (title), buffy, mutt_b2s (defaultsel));
        break;
 
       case OP_BUFFY_LIST:
@@ -1356,6 +1390,7 @@ bail:
   mutt_buffer_pool_release (&prefix);
   mutt_buffer_pool_release (&tmp);
   mutt_buffer_pool_release (&OldLastDir);
+  mutt_buffer_pool_release (&defaultsel);
 
   if (menu)
   {
index 277444aaee3657fcae2552a148042faacd23347b..fee412d6e8934ba559ccb2f32bc5b031cc593d98 100644 (file)
@@ -229,7 +229,7 @@ fail:
 }
 
 /* imap_mailbox_create: Prompt for a new mailbox name, and try to create it */
-int imap_mailbox_create (const char* folder)
+int imap_mailbox_create (const char* folder, BUFFER *result)
 {
   IMAP_DATA* idata;
   IMAP_MBOX mx;
@@ -272,6 +272,8 @@ int imap_mailbox_create (const char* folder)
   if (imap_create_mailbox (idata, buf) < 0)
     goto fail;
 
+  imap_buffer_qualify_path (result, &mx, buf);
+
   mutt_message _("Mailbox created.");
   mutt_sleep (0);
 
@@ -283,7 +285,7 @@ fail:
   return -1;
 }
 
-int imap_mailbox_rename(const char* mailbox)
+int imap_mailbox_rename(const char* mailbox, BUFFER *result)
 {
   IMAP_DATA* idata;
   IMAP_MBOX mx;
@@ -331,6 +333,8 @@ int imap_mailbox_rename(const char* mailbox)
     goto fail;
   }
 
+  imap_buffer_qualify_path (result, &mx, buf);
+
   mutt_message (_("Mailbox renamed."));
   mutt_sleep (0);
 
index fe99472b7e8d063a5740581595c1da02dc6cff46..24001c5e4bca1589f37da9118261842e4bc14017 100644 (file)
@@ -51,8 +51,8 @@ extern struct mx_ops mx_imap_ops;
 
 /* browse.c */
 int imap_browse (const char* path, struct browser_state* state);
-int imap_mailbox_create (const char* folder);
-int imap_mailbox_rename (const char* mailbox);
+int imap_mailbox_create (const char* folder, BUFFER *result);
+int imap_mailbox_rename (const char* mailbox, BUFFER *result);
 
 /* message.c */
 int imap_append_message (CONTEXT* ctx, MESSAGE* msg);
index 7d12ec2507b71883767fdcd3290aedd1d2659305..67376d2b9cb9a39d2b4bcd1b8fc0f52711daf4e6 100644 (file)
@@ -323,6 +323,7 @@ char* imap_next_word (char* s);
 time_t imap_parse_date (char* s);
 void imap_make_date (char* buf, time_t timestamp);
 void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path);
+void imap_buffer_qualify_path (BUFFER *dest, IMAP_MBOX *mx, char* path);
 void imap_quote_string (char* dest, size_t dlen, const char* src);
 void imap_quote_string_and_backquotes (char *dest, size_t dlen, const char *src);
 void imap_unquote_string (char* s);
index 01b57d08fbb241f22851dbbc163c5afee63b0c7e..315e77d85d9c5642fbe652d70f2279eeaa2b36c3 100644 (file)
@@ -707,6 +707,16 @@ void imap_qualify_path (char *dest, size_t len, IMAP_MBOX *mx, char* path)
   url_ciss_tostring (&url, dest, len, 0);
 }
 
+void imap_buffer_qualify_path (BUFFER *dest, IMAP_MBOX *mx, char* path)
+{
+  ciss_url_t url;
+
+  mutt_account_tourl (&mx->account, &url);
+  url.path = path;
+
+  url_ciss_tobuffer (&url, dest, 0);
+}
+
 
 static void _imap_quote_string (char *dest, size_t dlen, const char *src,
                                 const char *to_quote)
diff --git a/init.h b/init.h
index 2f450a43cee94546d881c5be54a6d38e17ce8368..39e5d8cd98efd0e31f2e6c70ed29f415b496abb8 100644 (file)
--- a/init.h
+++ b/init.h
@@ -422,6 +422,15 @@ struct option_t MuttVars[] = {
   ** doesn't make intuitive sense.  In those cases, it may be
   ** desirable to \fIunset\fP this variable.
   */
+  { "browser_sticky_cursor", DT_BOOL, R_NONE, {.l=OPTBROWSERSTICKYCURSOR}, {.l=1} },
+  /*
+  ** .pp
+  ** When this variable is \fIset\fP, the browser will attempt to keep
+  ** the cursor on the same mailbox when performing various functions.
+  ** These include moving up a directory, toggling between mailboxes
+  ** and directory listing, creating/renaming a mailbox, toggling
+  ** subscribed mailboxes, and entering a new mask.
+  */
 #if defined(USE_SSL)
   { "certificate_file",        DT_PATH, R_NONE, {.p=&SslCertFile}, {.p="~/.mutt_certificates"} },
   /*
diff --git a/mutt.h b/mutt.h
index ce9056d7acea031f965937a6dc1ff9255b73022d..549a4dde3aa9e8028d28577da5ddc9591f3d7f60 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -392,6 +392,7 @@ enum
   OPTCHANGEFOLDERNEXT,
   OPTBRAILLEFRIENDLY,
   OPTBROWSERABBRMAILBOXES,
+  OPTBROWSERSTICKYCURSOR,
   OPTCHECKMBOXSIZE,
   OPTCHECKNEW,
   OPTCOLLAPSEUNREAD,