]> granicus.if.org Git - vim/commitdiff
patch 8.0.1139: using window toolbar changes state v8.0.1139
authorBram Moolenaar <Bram@vim.org>
Sat, 23 Sep 2017 14:33:50 +0000 (16:33 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 23 Sep 2017 14:33:50 +0000 (16:33 +0200)
Problem:    Using window toolbar changes state.
Solution:   Always execute window toolbar actions in Normal mode.

src/ex_docmd.c
src/menu.c
src/proto/ex_docmd.pro
src/structs.h
src/version.c

index 29435c2ea8bee03c06927ee4fdfd6eab1da1b2d9..c740d037f55498eab4946ec5d5b65a81675b89c7 100644 (file)
@@ -10106,20 +10106,62 @@ update_topline_cursor(void)
     update_curswant();
 }
 
+/*
+ * Save the current State and go to Normal mode.
+ * Return TRUE if the typeahead could be saved.
+ */
+    int
+save_current_state(save_state_T *sst)
+{
+    sst->save_msg_scroll = msg_scroll;
+    sst->save_restart_edit = restart_edit;
+    sst->save_msg_didout = msg_didout;
+    sst->save_State = State;
+    sst->save_insertmode = p_im;
+    sst->save_finish_op = finish_op;
+    sst->save_opcount = opcount;
+
+    msg_scroll = FALSE;            /* no msg scrolling in Normal mode */
+    restart_edit = 0;      /* don't go to Insert mode */
+    p_im = FALSE;          /* don't use 'insertmode' */
+
+    /*
+     * Save the current typeahead.  This is required to allow using ":normal"
+     * from an event handler and makes sure we don't hang when the argument
+     * ends with half a command.
+     */
+    save_typeahead(&sst->tabuf);
+    return sst->tabuf.typebuf_valid;
+}
+
+    void
+restore_current_state(save_state_T *sst)
+{
+    /* Restore the previous typeahead. */
+    restore_typeahead(&sst->tabuf);
+
+    msg_scroll = sst->save_msg_scroll;
+    restart_edit = sst->save_restart_edit;
+    p_im = sst->save_insertmode;
+    finish_op = sst->save_finish_op;
+    opcount = sst->save_opcount;
+    msg_didout |= sst->save_msg_didout;        /* don't reset msg_didout now */
+
+    /* Restore the state (needed when called from a function executed for
+     * 'indentexpr'). Update the mouse and cursor, they may have changed. */
+    State = sst->save_State;
+#ifdef CURSOR_SHAPE
+    ui_cursor_shape();         /* may show different cursor shape */
+#endif
+}
+
 /*
  * ":normal[!] {commands}": Execute normal mode commands.
  */
     void
 ex_normal(exarg_T *eap)
 {
-    int                save_msg_scroll = msg_scroll;
-    int                save_restart_edit = restart_edit;
-    int                save_msg_didout = msg_didout;
-    int                save_State = State;
-    tasave_T   tabuf;
-    int                save_insertmode = p_im;
-    int                save_finish_op = finish_op;
-    int                save_opcount = opcount;
+    save_state_T save_state;
 #ifdef FEAT_MBYTE
     char_u     *arg = NULL;
     int                l;
@@ -10136,11 +10178,6 @@ ex_normal(exarg_T *eap)
        EMSG(_("E192: Recursive use of :normal too deep"));
        return;
     }
-    ++ex_normal_busy;
-
-    msg_scroll = FALSE;            /* no msg scrolling in Normal mode */
-    restart_edit = 0;      /* don't go to Insert mode */
-    p_im = FALSE;          /* don't use 'insertmode' */
 
 #ifdef FEAT_MBYTE
     /*
@@ -10206,13 +10243,8 @@ ex_normal(exarg_T *eap)
     }
 #endif
 
-    /*
-     * Save the current typeahead.  This is required to allow using ":normal"
-     * from an event handler and makes sure we don't hang when the argument
-     * ends with half a command.
-     */
-    save_typeahead(&tabuf);
-    if (tabuf.typebuf_valid)
+    ++ex_normal_busy;
+    if (save_current_state(&save_state))
     {
        /*
         * Repeat the :normal command for each line in the range.  When no
@@ -10240,20 +10272,8 @@ ex_normal(exarg_T *eap)
     /* Might not return to the main loop when in an event handler. */
     update_topline_cursor();
 
-    /* Restore the previous typeahead. */
-    restore_typeahead(&tabuf);
-
+    restore_current_state(&save_state);
     --ex_normal_busy;
-    msg_scroll = save_msg_scroll;
-    restart_edit = save_restart_edit;
-    p_im = save_insertmode;
-    finish_op = save_finish_op;
-    opcount = save_opcount;
-    msg_didout |= save_msg_didout;     /* don't reset msg_didout now */
-
-    /* Restore the state (needed when called from a function executed for
-     * 'indentexpr'). Update the mouse and cursor, they may have changed. */
-    State = save_State;
 #ifdef FEAT_MOUSE
     setmouse();
 #endif
index 1ad8a5cb90e5c4147731d8513729c69b7d44bbf7..f07be97e74840b1eba3b3e74087fda8aaabeab09 100644 (file)
@@ -2242,7 +2242,7 @@ gui_destroy_tearoffs_recurse(vimmenu_T *menu)
 execute_menu(exarg_T *eap, vimmenu_T *menu)
 {
     char_u     *mode;
-    int                idx;
+    int                idx = -1;
 
     /* Use the Insert mode entry when returning to Insert mode. */
     if (restart_edit
@@ -2306,7 +2306,9 @@ execute_menu(exarg_T *eap, vimmenu_T *menu)
        if (*p_sel == 'e' && gchar_cursor() != NUL)
            ++curwin->w_cursor.col;
     }
-    else
+
+    /* For the WinBar menu always use the Normal mode menu. */
+    if (idx == -1 || eap == NULL)
     {
        mode = (char_u *)"Normal";
        idx = MENU_INDEX_NORMAL;
@@ -2322,8 +2324,16 @@ execute_menu(exarg_T *eap, vimmenu_T *menu)
                || current_SID != 0
 #endif
           )
-           exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
+       {
+           save_state_T save_state;
+
+           ++ex_normal_busy;
+           if (save_current_state(&save_state))
+               exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
                                                           menu->silent[idx]);
+           restore_current_state(&save_state);
+           --ex_normal_busy;
+       }
        else
            ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
                                                     TRUE, menu->silent[idx]);
@@ -2406,12 +2416,18 @@ winbar_click(win_T *wp, int col)
        if (col >= item->wb_startcol && col <= item->wb_endcol)
        {
            win_T *save_curwin = NULL;
+           pos_T   save_visual = VIsual;
+           int     save_visual_active = VIsual_active;
+           int     save_visual_select = VIsual_select;
+           int     save_visual_reselect = VIsual_reselect;
+           int     save_visual_mode = VIsual_mode;
 
            if (wp != curwin)
            {
                /* Clicking in the window toolbar of a not-current window.
-                * Make that window the current one and go to Normal mode. */
+                * Make that window the current one and save Visual mode. */
                save_curwin = curwin;
+               VIsual_active = FALSE;
                curwin = wp;
                curbuf = curwin->w_buffer;
                check_cursor();
@@ -2423,6 +2439,11 @@ winbar_click(win_T *wp, int col)
            {
                curwin = save_curwin;
                curbuf = curwin->w_buffer;
+               VIsual = save_visual;
+               VIsual_active = save_visual_active;
+               VIsual_select = save_visual_select;
+               VIsual_reselect = save_visual_reselect;
+               VIsual_mode = save_visual_mode;
            }
        }
     }
index 116ff4e7296bd6bac458f64e464b95f1fd80d17f..3819531929088eed30430f6431ebfa3707e7ec1d 100644 (file)
@@ -51,6 +51,8 @@ void ex_redraw(exarg_T *eap);
 int vim_mkdir_emsg(char_u *name, int prot);
 FILE *open_exfile(char_u *fname, int forceit, char *mode);
 void update_topline_cursor(void);
+int save_current_state(save_state_T *sst);
+void restore_current_state(save_state_T *sst);
 void ex_normal(exarg_T *eap);
 void exec_normal_cmd(char_u *cmd, int remap, int silent);
 void exec_normal(int was_typed);
index 4582dca95b4528fedbaa1129804c358c65b5504b..946857be5e2c268e7a3b9ddfe60992072c2160c9 100644 (file)
@@ -3405,3 +3405,16 @@ typedef struct lval_S
     dictitem_T *ll_di;         /* The dictitem or NULL */
     char_u     *ll_newkey;     /* New key for Dict in alloc. mem or NULL. */
 } lval_T;
+
+/* Structure used to save the current state.  Used when executing Normal mode
+ * commands while in any other mode. */
+typedef struct {
+    int                save_msg_scroll;
+    int                save_restart_edit;
+    int                save_msg_didout;
+    int                save_State;
+    int                save_insertmode;
+    int                save_finish_op;
+    int                save_opcount;
+    tasave_T   tabuf;
+} save_state_T;
index a2f71a3d9b1b0abe3bd38f2ebc5746bbafead26e..3d5716e4c6f6e8a529700e5a724fe85a745936b8 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1139,
 /**/
     1138,
 /**/