Skip to content

Commit a21a6a9

Browse files
committed
patch 8.0.1139: using window toolbar changes state
Problem: Using window toolbar changes state. Solution: Always execute window toolbar actions in Normal mode.
1 parent eb163d7 commit a21a6a9

File tree

5 files changed

+95
-37
lines changed

5 files changed

+95
-37
lines changed

src/ex_docmd.c

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10106,20 +10106,62 @@ update_topline_cursor(void)
1010610106
update_curswant();
1010710107
}
1010810108

10109+
/*
10110+
* Save the current State and go to Normal mode.
10111+
* Return TRUE if the typeahead could be saved.
10112+
*/
10113+
int
10114+
save_current_state(save_state_T *sst)
10115+
{
10116+
sst->save_msg_scroll = msg_scroll;
10117+
sst->save_restart_edit = restart_edit;
10118+
sst->save_msg_didout = msg_didout;
10119+
sst->save_State = State;
10120+
sst->save_insertmode = p_im;
10121+
sst->save_finish_op = finish_op;
10122+
sst->save_opcount = opcount;
10123+
10124+
msg_scroll = FALSE; /* no msg scrolling in Normal mode */
10125+
restart_edit = 0; /* don't go to Insert mode */
10126+
p_im = FALSE; /* don't use 'insertmode' */
10127+
10128+
/*
10129+
* Save the current typeahead. This is required to allow using ":normal"
10130+
* from an event handler and makes sure we don't hang when the argument
10131+
* ends with half a command.
10132+
*/
10133+
save_typeahead(&sst->tabuf);
10134+
return sst->tabuf.typebuf_valid;
10135+
}
10136+
10137+
void
10138+
restore_current_state(save_state_T *sst)
10139+
{
10140+
/* Restore the previous typeahead. */
10141+
restore_typeahead(&sst->tabuf);
10142+
10143+
msg_scroll = sst->save_msg_scroll;
10144+
restart_edit = sst->save_restart_edit;
10145+
p_im = sst->save_insertmode;
10146+
finish_op = sst->save_finish_op;
10147+
opcount = sst->save_opcount;
10148+
msg_didout |= sst->save_msg_didout; /* don't reset msg_didout now */
10149+
10150+
/* Restore the state (needed when called from a function executed for
10151+
* 'indentexpr'). Update the mouse and cursor, they may have changed. */
10152+
State = sst->save_State;
10153+
#ifdef CURSOR_SHAPE
10154+
ui_cursor_shape(); /* may show different cursor shape */
10155+
#endif
10156+
}
10157+
1010910158
/*
1011010159
* ":normal[!] {commands}": Execute normal mode commands.
1011110160
*/
1011210161
void
1011310162
ex_normal(exarg_T *eap)
1011410163
{
10115-
int save_msg_scroll = msg_scroll;
10116-
int save_restart_edit = restart_edit;
10117-
int save_msg_didout = msg_didout;
10118-
int save_State = State;
10119-
tasave_T tabuf;
10120-
int save_insertmode = p_im;
10121-
int save_finish_op = finish_op;
10122-
int save_opcount = opcount;
10164+
save_state_T save_state;
1012310165
#ifdef FEAT_MBYTE
1012410166
char_u *arg = NULL;
1012510167
int l;
@@ -10136,11 +10178,6 @@ ex_normal(exarg_T *eap)
1013610178
EMSG(_("E192: Recursive use of :normal too deep"));
1013710179
return;
1013810180
}
10139-
++ex_normal_busy;
10140-
10141-
msg_scroll = FALSE; /* no msg scrolling in Normal mode */
10142-
restart_edit = 0; /* don't go to Insert mode */
10143-
p_im = FALSE; /* don't use 'insertmode' */
1014410181

1014510182
#ifdef FEAT_MBYTE
1014610183
/*
@@ -10206,13 +10243,8 @@ ex_normal(exarg_T *eap)
1020610243
}
1020710244
#endif
1020810245

10209-
/*
10210-
* Save the current typeahead. This is required to allow using ":normal"
10211-
* from an event handler and makes sure we don't hang when the argument
10212-
* ends with half a command.
10213-
*/
10214-
save_typeahead(&tabuf);
10215-
if (tabuf.typebuf_valid)
10246+
++ex_normal_busy;
10247+
if (save_current_state(&save_state))
1021610248
{
1021710249
/*
1021810250
* Repeat the :normal command for each line in the range. When no
@@ -10240,20 +10272,8 @@ ex_normal(exarg_T *eap)
1024010272
/* Might not return to the main loop when in an event handler. */
1024110273
update_topline_cursor();
1024210274

10243-
/* Restore the previous typeahead. */
10244-
restore_typeahead(&tabuf);
10245-
10275+
restore_current_state(&save_state);
1024610276
--ex_normal_busy;
10247-
msg_scroll = save_msg_scroll;
10248-
restart_edit = save_restart_edit;
10249-
p_im = save_insertmode;
10250-
finish_op = save_finish_op;
10251-
opcount = save_opcount;
10252-
msg_didout |= save_msg_didout; /* don't reset msg_didout now */
10253-
10254-
/* Restore the state (needed when called from a function executed for
10255-
* 'indentexpr'). Update the mouse and cursor, they may have changed. */
10256-
State = save_State;
1025710277
#ifdef FEAT_MOUSE
1025810278
setmouse();
1025910279
#endif

src/menu.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,7 +2242,7 @@ gui_destroy_tearoffs_recurse(vimmenu_T *menu)
22422242
execute_menu(exarg_T *eap, vimmenu_T *menu)
22432243
{
22442244
char_u *mode;
2245-
int idx;
2245+
int idx = -1;
22462246

22472247
/* Use the Insert mode entry when returning to Insert mode. */
22482248
if (restart_edit
@@ -2306,7 +2306,9 @@ execute_menu(exarg_T *eap, vimmenu_T *menu)
23062306
if (*p_sel == 'e' && gchar_cursor() != NUL)
23072307
++curwin->w_cursor.col;
23082308
}
2309-
else
2309+
2310+
/* For the WinBar menu always use the Normal mode menu. */
2311+
if (idx == -1 || eap == NULL)
23102312
{
23112313
mode = (char_u *)"Normal";
23122314
idx = MENU_INDEX_NORMAL;
@@ -2322,8 +2324,16 @@ execute_menu(exarg_T *eap, vimmenu_T *menu)
23222324
|| current_SID != 0
23232325
#endif
23242326
)
2325-
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
2327+
{
2328+
save_state_T save_state;
2329+
2330+
++ex_normal_busy;
2331+
if (save_current_state(&save_state))
2332+
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
23262333
menu->silent[idx]);
2334+
restore_current_state(&save_state);
2335+
--ex_normal_busy;
2336+
}
23272337
else
23282338
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
23292339
TRUE, menu->silent[idx]);
@@ -2406,12 +2416,18 @@ winbar_click(win_T *wp, int col)
24062416
if (col >= item->wb_startcol && col <= item->wb_endcol)
24072417
{
24082418
win_T *save_curwin = NULL;
2419+
pos_T save_visual = VIsual;
2420+
int save_visual_active = VIsual_active;
2421+
int save_visual_select = VIsual_select;
2422+
int save_visual_reselect = VIsual_reselect;
2423+
int save_visual_mode = VIsual_mode;
24092424

24102425
if (wp != curwin)
24112426
{
24122427
/* Clicking in the window toolbar of a not-current window.
2413-
* Make that window the current one and go to Normal mode. */
2428+
* Make that window the current one and save Visual mode. */
24142429
save_curwin = curwin;
2430+
VIsual_active = FALSE;
24152431
curwin = wp;
24162432
curbuf = curwin->w_buffer;
24172433
check_cursor();
@@ -2423,6 +2439,11 @@ winbar_click(win_T *wp, int col)
24232439
{
24242440
curwin = save_curwin;
24252441
curbuf = curwin->w_buffer;
2442+
VIsual = save_visual;
2443+
VIsual_active = save_visual_active;
2444+
VIsual_select = save_visual_select;
2445+
VIsual_reselect = save_visual_reselect;
2446+
VIsual_mode = save_visual_mode;
24262447
}
24272448
}
24282449
}

src/proto/ex_docmd.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ void ex_redraw(exarg_T *eap);
5151
int vim_mkdir_emsg(char_u *name, int prot);
5252
FILE *open_exfile(char_u *fname, int forceit, char *mode);
5353
void update_topline_cursor(void);
54+
int save_current_state(save_state_T *sst);
55+
void restore_current_state(save_state_T *sst);
5456
void ex_normal(exarg_T *eap);
5557
void exec_normal_cmd(char_u *cmd, int remap, int silent);
5658
void exec_normal(int was_typed);

src/structs.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3405,3 +3405,16 @@ typedef struct lval_S
34053405
dictitem_T *ll_di; /* The dictitem or NULL */
34063406
char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */
34073407
} lval_T;
3408+
3409+
/* Structure used to save the current state. Used when executing Normal mode
3410+
* commands while in any other mode. */
3411+
typedef struct {
3412+
int save_msg_scroll;
3413+
int save_restart_edit;
3414+
int save_msg_didout;
3415+
int save_State;
3416+
int save_insertmode;
3417+
int save_finish_op;
3418+
int save_opcount;
3419+
tasave_T tabuf;
3420+
} save_state_T;

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
1139,
764766
/**/
765767
1138,
766768
/**/

0 commit comments

Comments
 (0)