mirror of
https://github.com/neovim/neovim.git
synced 2025-09-18 17:28:23 +00:00
vim-patch:8.0.1139: using window toolbar changes state
Problem: Using window toolbar changes state.
Solution: Always execute window toolbar actions in Normal mode.
a21a6a9ade
This commit is contained in:
@@ -334,7 +334,7 @@ typedef struct {
|
|||||||
// Struct to hold the saved typeahead for save_typeahead().
|
// Struct to hold the saved typeahead for save_typeahead().
|
||||||
typedef struct {
|
typedef struct {
|
||||||
typebuf_T save_typebuf;
|
typebuf_T save_typebuf;
|
||||||
int typebuf_valid; // TRUE when save_typebuf valid
|
bool typebuf_valid; // true when save_typebuf valid
|
||||||
int old_char;
|
int old_char;
|
||||||
int old_mod_mask;
|
int old_mod_mask;
|
||||||
buffheader_T save_readbuf1;
|
buffheader_T save_readbuf1;
|
||||||
|
@@ -8209,6 +8209,57 @@ void update_topline_cursor(void)
|
|||||||
update_curswant();
|
update_curswant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the current State and go to Normal mode.
|
||||||
|
// Return true if the typeahead could be saved.
|
||||||
|
bool save_current_state(save_state_T *sst)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
sst->save_reg_executing = reg_executing;
|
||||||
|
|
||||||
|
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)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
// Restore the previous typeahead.
|
||||||
|
restore_typeahead(&sst->tabuf);
|
||||||
|
|
||||||
|
msg_scroll = sst->save_msg_scroll;
|
||||||
|
if (force_restart_edit) {
|
||||||
|
force_restart_edit = false;
|
||||||
|
} else {
|
||||||
|
// Some function (terminal_enter()) was aware of ex_normal and decided to
|
||||||
|
// override the value of restart_edit anyway.
|
||||||
|
restart_edit = sst->save_restart_edit;
|
||||||
|
}
|
||||||
|
p_im = sst->save_insertmode;
|
||||||
|
finish_op = sst->save_finish_op;
|
||||||
|
opcount = sst->save_opcount;
|
||||||
|
reg_executing = sst->save_reg_executing;
|
||||||
|
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;
|
||||||
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ":normal[!] {commands}": Execute normal mode commands.
|
* ":normal[!] {commands}": Execute normal mode commands.
|
||||||
*/
|
*/
|
||||||
@@ -8218,15 +8269,7 @@ static void ex_normal(exarg_T *eap)
|
|||||||
EMSG("Can't re-enter normal mode from terminal mode");
|
EMSG("Can't re-enter normal mode from terminal mode");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int save_msg_scroll = msg_scroll;
|
save_state_T save_state;
|
||||||
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;
|
|
||||||
long save_opcount = opcount;
|
|
||||||
const int save_reg_executing = reg_executing;
|
|
||||||
char_u *arg = NULL;
|
char_u *arg = NULL;
|
||||||
int l;
|
int l;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
@@ -8239,11 +8282,6 @@ static void ex_normal(exarg_T *eap)
|
|||||||
EMSG(_("E192: Recursive use of :normal too deep"));
|
EMSG(_("E192: Recursive use of :normal too deep"));
|
||||||
return;
|
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' */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vgetc() expects a CSI and K_SPECIAL to have been escaped. Don't do
|
* vgetc() expects a CSI and K_SPECIAL to have been escaped. Don't do
|
||||||
@@ -8277,19 +8315,11 @@ static void ex_normal(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
ex_normal_busy++;
|
||||||
* Save the current typeahead. This is required to allow using ":normal"
|
if (save_current_state(&save_state)) {
|
||||||
* from an event handler and makes sure we don't hang when the argument
|
// Repeat the :normal command for each line in the range. When no
|
||||||
* ends with half a command.
|
// range given, execute it just once, without positioning the cursor
|
||||||
*/
|
// first.
|
||||||
save_typeahead(&tabuf);
|
|
||||||
// TODO(philix): after save_typeahead() this is always TRUE
|
|
||||||
if (tabuf.typebuf_valid) {
|
|
||||||
/*
|
|
||||||
* Repeat the :normal command for each line in the range. When no
|
|
||||||
* range given, execute it just once, without positioning the cursor
|
|
||||||
* first.
|
|
||||||
*/
|
|
||||||
do {
|
do {
|
||||||
if (eap->addr_count != 0) {
|
if (eap->addr_count != 0) {
|
||||||
curwin->w_cursor.lnum = eap->line1++;
|
curwin->w_cursor.lnum = eap->line1++;
|
||||||
@@ -8306,29 +8336,12 @@ static void ex_normal(exarg_T *eap)
|
|||||||
/* Might not return to the main loop when in an event handler. */
|
/* Might not return to the main loop when in an event handler. */
|
||||||
update_topline_cursor();
|
update_topline_cursor();
|
||||||
|
|
||||||
/* Restore the previous typeahead. */
|
restore_current_state(&save_state);
|
||||||
restore_typeahead(&tabuf);
|
|
||||||
|
|
||||||
--ex_normal_busy;
|
ex_normal_busy--;
|
||||||
msg_scroll = save_msg_scroll;
|
|
||||||
if (force_restart_edit) {
|
|
||||||
force_restart_edit = false;
|
|
||||||
} else {
|
|
||||||
// Some function (terminal_enter()) was aware of ex_normal and decided to
|
|
||||||
// override the value of restart_edit anyway.
|
|
||||||
restart_edit = save_restart_edit;
|
|
||||||
}
|
|
||||||
p_im = save_insertmode;
|
|
||||||
finish_op = save_finish_op;
|
|
||||||
opcount = save_opcount;
|
|
||||||
reg_executing = save_reg_executing;
|
|
||||||
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;
|
|
||||||
setmouse();
|
setmouse();
|
||||||
ui_cursor_shape(); /* may show different cursor shape */
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
xfree(arg);
|
xfree(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,6 +20,20 @@
|
|||||||
#define EXMODE_NORMAL 1
|
#define EXMODE_NORMAL 1
|
||||||
#define EXMODE_VIM 2
|
#define EXMODE_VIM 2
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
bool save_finish_op;
|
||||||
|
long save_opcount;
|
||||||
|
int save_reg_executing;
|
||||||
|
tasave_T tabuf;
|
||||||
|
} save_state_T;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "ex_docmd.h.generated.h"
|
# include "ex_docmd.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1216,7 +1216,7 @@ void save_typeahead(tasave_T *tp)
|
|||||||
{
|
{
|
||||||
tp->save_typebuf = typebuf;
|
tp->save_typebuf = typebuf;
|
||||||
alloc_typebuf();
|
alloc_typebuf();
|
||||||
tp->typebuf_valid = TRUE;
|
tp->typebuf_valid = true;
|
||||||
tp->old_char = old_char;
|
tp->old_char = old_char;
|
||||||
tp->old_mod_mask = old_mod_mask;
|
tp->old_mod_mask = old_mod_mask;
|
||||||
old_char = -1;
|
old_char = -1;
|
||||||
|
@@ -1410,7 +1410,7 @@ static int menu_is_hidden(char_u *name)
|
|||||||
static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
|
static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
|
||||||
FUNC_ATTR_NONNULL_ARG(2)
|
FUNC_ATTR_NONNULL_ARG(2)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx = -1;
|
||||||
char_u *mode;
|
char_u *mode;
|
||||||
|
|
||||||
// Use the Insert mode entry when returning to Insert mode.
|
// Use the Insert mode entry when returning to Insert mode.
|
||||||
@@ -1464,9 +1464,13 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
|
|||||||
|
|
||||||
/* Adjust the cursor to make sure it is in the correct pos
|
/* Adjust the cursor to make sure it is in the correct pos
|
||||||
* for exclusive mode */
|
* for exclusive mode */
|
||||||
if (*p_sel == 'e' && gchar_cursor() != NUL)
|
if (*p_sel == 'e' && gchar_cursor() != NUL) {
|
||||||
++curwin->w_cursor.col;
|
curwin->w_cursor.col++;
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the WinBar menu always use the Normal mode menu.
|
||||||
|
if (idx == -1 || eap == NULL) {
|
||||||
mode = (char_u *)"Normal";
|
mode = (char_u *)"Normal";
|
||||||
idx = MENU_INDEX_NORMAL;
|
idx = MENU_INDEX_NORMAL;
|
||||||
}
|
}
|
||||||
@@ -1477,8 +1481,15 @@ static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
|
|||||||
// Also for the window toolbar
|
// Also for the window toolbar
|
||||||
// Otherwise put them in the typeahead buffer.
|
// Otherwise put them in the typeahead buffer.
|
||||||
if (eap == NULL || current_sctx.sc_sid != 0) {
|
if (eap == NULL || current_sctx.sc_sid != 0) {
|
||||||
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
|
save_state_T save_state;
|
||||||
menu->silent[idx]);
|
|
||||||
|
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 {
|
} else {
|
||||||
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0, true,
|
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0, true,
|
||||||
menu->silent[idx]);
|
menu->silent[idx]);
|
||||||
@@ -1540,11 +1551,17 @@ void winbar_click(win_T *wp, int col)
|
|||||||
|
|
||||||
if (col >= item->wb_startcol && col <= item->wb_endcol) {
|
if (col >= item->wb_startcol && col <= item->wb_endcol) {
|
||||||
win_T *save_curwin = NULL;
|
win_T *save_curwin = NULL;
|
||||||
|
const pos_T save_visual = VIsual;
|
||||||
|
const int save_visual_active = VIsual_active;
|
||||||
|
const int save_visual_select = VIsual_select;
|
||||||
|
const int save_visual_reselect = VIsual_reselect;
|
||||||
|
const int save_visual_mode = VIsual_mode;
|
||||||
|
|
||||||
if (wp != curwin) {
|
if (wp != curwin) {
|
||||||
// Clicking in the window toolbar of a not-current window.
|
// 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;
|
save_curwin = curwin;
|
||||||
|
VIsual_active = false;
|
||||||
curwin = wp;
|
curwin = wp;
|
||||||
curbuf = curwin->w_buffer;
|
curbuf = curwin->w_buffer;
|
||||||
check_cursor();
|
check_cursor();
|
||||||
@@ -1555,6 +1572,11 @@ void winbar_click(win_T *wp, int col)
|
|||||||
if (save_curwin != NULL) {
|
if (save_curwin != NULL) {
|
||||||
curwin = save_curwin;
|
curwin = save_curwin;
|
||||||
curbuf = curwin->w_buffer;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user