aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/edit.c11
-rw-r--r--src/nvim/ex_docmd.c13
-rw-r--r--src/nvim/globals.h2
3 files changed, 24 insertions, 2 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 6bcf5e804a..427623e052 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -254,7 +254,16 @@ edit (
)
{
if (curbuf->terminal) {
- terminal_enter();
+ if (ex_normal_busy) {
+ // don't enter terminal mode from `ex_normal`, which can result in all
+ // kinds of havoc(such as terminal mode recursiveness). Instead, set a
+ // flag that allow us to force-set the value of `restart_edit` before
+ // `ex_normal` returns
+ restart_edit = 'i';
+ force_restart_edit = true;
+ } else {
+ terminal_enter();
+ }
return false;
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index d69d106dc6..3c09a3a2f8 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7624,6 +7624,10 @@ void update_topline_cursor(void)
*/
static void ex_normal(exarg_T *eap)
{
+ if (curbuf->terminal) {
+ EMSG("Can't re-enter normal mode from terminal mode");
+ return;
+ }
int save_msg_scroll = msg_scroll;
int save_restart_edit = restart_edit;
int save_msg_didout = msg_didout;
@@ -7715,7 +7719,14 @@ static void ex_normal(exarg_T *eap)
--ex_normal_busy;
msg_scroll = save_msg_scroll;
- restart_edit = save_restart_edit;
+ if (force_restart_edit) {
+ force_restart_edit = false;
+ } else {
+ // some function called was aware of ex_normal and decided to override the
+ // value of restart_edit anyway. So far only used in terminal mode(see
+ // terminal_enter() in edit.c)
+ restart_edit = save_restart_edit;
+ }
p_im = save_insertmode;
finish_op = save_finish_op;
opcount = save_opcount;
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 183e8fcff2..60d03cec0c 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -823,6 +823,8 @@ EXTERN int no_u_sync INIT(= 0); /* Don't call u_sync() */
EXTERN int u_sync_once INIT(= 0); /* Call u_sync() once when evaluating
an expression. */
+EXTERN bool force_restart_edit INIT(= false); // force restart_edit after
+ // ex_normal returns
EXTERN int restart_edit INIT(= 0); /* call edit when next cmd finished */
EXTERN int arrow_used; /* Normally FALSE, set to TRUE after
* hitting cursor key in insert mode.