From 6d41c78e353b630bc1a72cbff9160311d2a81e8c Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 6 Jun 2018 09:11:12 +0200 Subject: [PATCH] patch 8.1.0035: not easy to switch between prompt buffer and other windows 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. --- src/edit.c | 33 +++++++++++++++++++++++++++++++++ src/ex_docmd.c | 3 ++- src/structs.h | 2 ++ src/version.c | 2 ++ src/window.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/edit.c b/src/edit.c index 1b79eccac..76cbfce54 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 82dd0491d..342dec222 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 cbebd7f96..e76acc832 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 a3f5c052f..c7c5bfd77 100644 --- a/src/version.c +++ b/src/version.c @@ -761,6 +761,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 35, /**/ 34, /**/ diff --git a/src/window.c b/src/window.c index d3ec4cd02..f86d11eb3 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) -- 2.40.0