summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-06-06 09:11:12 +0200
committerBram Moolenaar <Bram@vim.org>2018-06-06 09:11:12 +0200
commit6d41c78e353b630bc1a72cbff9160311d2a81e8c (patch)
tree4ed89d974b7ce1e69ae848bfea2802605c748453
parentadb8fbec4f4059d214fe6acf2485ffd35e803450 (diff)
patch 8.1.0035: not easy to switch between prompt buffer and other windowsv8.1.0035
Problem: Not easy to switch between prompt buffer and other windows. Solution: Accept CTRL-W commands in Insert mode. Start and stop Insert mode as one would expect.
-rw-r--r--src/edit.c33
-rw-r--r--src/ex_docmd.c3
-rw-r--r--src/structs.h2
-rw-r--r--src/version.c2
-rw-r--r--src/window.c43
5 files changed, 82 insertions, 1 deletions
diff --git a/src/edit.c b/src/edit.c
index 1b79eccac9..76cbfce549 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -811,6 +811,14 @@ edit(
do
{
c = safe_vgetc();
+
+ if (stop_insert_mode)
+ {
+ // Insert mode ended, possibly from a callback.
+ count = 0;
+ nomove = TRUE;
+ goto doESCkey;
+ }
} while (c == K_IGNORE || c == K_NOP);
/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
@@ -1165,6 +1173,18 @@ doESCkey:
break;
case Ctrl_W: /* delete word before the cursor */
+#ifdef FEAT_JOB_CHANNEL
+ if (bt_prompt(curbuf) && (mod_mask & MOD_MASK_SHIFT) == 0)
+ {
+ // In a prompt window CTRL-W is used for window commands.
+ // Use Shift-CTRL-W to delete a word.
+ stuffcharReadbuff(Ctrl_W);
+ restart_edit = 'i';
+ nomove = TRUE;
+ count = 0;
+ goto doESCkey;
+ }
+#endif
did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
auto_format(FALSE, TRUE);
break;
@@ -1869,6 +1889,19 @@ init_prompt(int cmdchar_todo)
coladvance((colnr_T)MAXCOL);
changed_bytes(curbuf->b_ml.ml_line_count, 0);
}
+
+ // Insert always starts after the prompt, allow editing text after it.
+ if (Insstart_orig.lnum != curwin->w_cursor.lnum
+ || Insstart_orig.col != (int)STRLEN(prompt))
+ {
+ Insstart.lnum = curwin->w_cursor.lnum;
+ Insstart.col = STRLEN(prompt);
+ Insstart_orig = Insstart;
+ Insstart_textlen = Insstart.col;
+ Insstart_blank_vcol = MAXCOL;
+ arrow_used = FALSE;
+ }
+
if (cmdchar_todo == 'A')
coladvance((colnr_T)MAXCOL);
if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt))
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 82dd0491d4..342dec2229 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -7341,7 +7341,8 @@ ex_close(exarg_T *eap)
{
if (eap->addr_count == 0)
ex_win_close(eap->forceit, curwin, NULL);
- else {
+ else
+ {
FOR_ALL_WINDOWS(win)
{
winnr++;
diff --git a/src/structs.h b/src/structs.h
index cbebd7f964..e76acc8323 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -2360,6 +2360,8 @@ struct file_buffer
char_u *b_prompt_text; // set by prompt_setprompt()
char_u *b_prompt_callback; // set by prompt_setcallback()
partial_T *b_prompt_partial; // set by prompt_setcallback()
+ int b_prompt_insert; // value for restart_edit when entering
+ // a prompt buffer window.
#endif
#ifdef FEAT_MZSCHEME
void *b_mzscheme_ref; /* The MzScheme reference to this buffer */
diff --git a/src/version.c b/src/version.c
index a3f5c052fe..c7c5bfd779 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 35,
+/**/
34,
/**/
33,
diff --git a/src/window.c b/src/window.c
index d3ec4cd025..f86d11eb3b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2103,6 +2103,29 @@ win_equal_rec(
}
}
+#ifdef FEAT_JOB_CHANNEL
+ static void
+leaving_window(win_T *win)
+{
+ // When leaving a prompt window stop Insert mode and perhaps restart
+ // it when entering that window again.
+ win->w_buffer->b_prompt_insert = restart_edit;
+ restart_edit = NUL;
+
+ // When leaving the window (or closing the window) was done from a
+ // callback we need to break out of the Insert mode loop.
+ if (State & INSERT)
+ stop_insert_mode = TRUE;
+}
+
+ static void
+entering_window(win_T *win)
+{
+ // When entering the prompt window may restart Insert mode.
+ restart_edit = win->w_buffer->b_prompt_insert;
+}
+#endif
+
/*
* Close all windows for buffer "buf".
*/
@@ -2231,6 +2254,9 @@ close_last_window_tabpage(
if (h != tabline_height())
shell_new_rows();
}
+#ifdef FEAT_JOB_CHANNEL
+ entering_window(curwin);
+#endif
/* Since goto_tabpage_tp above did not trigger *Enter autocommands, do
* that now. */
apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
@@ -2296,6 +2322,9 @@ win_close(win_T *win, int free_buf)
if (win == curwin)
{
+#ifdef FEAT_JOB_CHANNEL
+ leaving_window(curwin);
+#endif
/*
* Guess which window is going to be the new current window.
* This may change because of the autocommands (sigh).
@@ -3649,6 +3678,9 @@ win_new_tabpage(int after)
* scrollbars. Have to update them anyway. */
gui_may_update_scrollbars();
#endif
+#ifdef FEAT_JOB_CHANNEL
+ entering_window(curwin);
+#endif
redraw_all_later(CLEAR);
apply_autocmds(EVENT_WINNEW, NULL, NULL, FALSE, curbuf);
@@ -3822,6 +3854,9 @@ leave_tabpage(
{
tabpage_T *tp = curtab;
+#ifdef FEAT_JOB_CHANNEL
+ leaving_window(curwin);
+#endif
reset_VIsual_and_resel(); /* stop Visual mode */
if (trigger_leave_autocmds)
{
@@ -4318,6 +4353,11 @@ win_enter_ext(
if (wp == curwin && !curwin_invalid) /* nothing to do */
return;
+#ifdef FEAT_JOB_CHANNEL
+ if (!curwin_invalid)
+ leaving_window(curwin);
+#endif
+
if (!curwin_invalid && trigger_leave_autocmds)
{
/*
@@ -4389,6 +4429,9 @@ win_enter_ext(
shorten_fnames(TRUE);
}
+#ifdef FEAT_JOB_CHANNEL
+ entering_window(curwin);
+#endif
if (trigger_new_autocmds)
apply_autocmds(EVENT_WINNEW, NULL, NULL, FALSE, curbuf);
if (trigger_enter_autocmds)