changeset 14103:d053ec57d886 v8.1.0069

patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer commit https://github.com/vim/vim/commit/0e5979a6d491f68c4a8c86fab489016919329a6b Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jun 17 19:36:33 2018 +0200 patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer Problem: Cannot handle pressing CTRL-C in a prompt buffer. Solution: Add prompt_setinterrupt().
author Christian Brabandt <cb@256bit.org>
date Sun, 17 Jun 2018 19:45:06 +0200
parents 6919feb4b26e
children 3c0cf1004a6c
files runtime/doc/eval.txt src/channel.c src/edit.c src/evalfunc.c src/proto/channel.pro src/version.c
diffstat 6 files changed, 98 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2297,8 +2297,9 @@ pow({x}, {y})			Float	{x} to the power o
 prevnonblank({lnum})		Number	line nr of non-blank line <= {lnum}
 printf({fmt}, {expr1}...)	String	format text
 prompt_addtext({buf}, {expr})	none	add text to a prompt buffer
+prompt_setcallback({buf}, {expr}) none	set prompt callback function
+prompt_setinterrupt({buf}, {text}) none	set prompt interrupt function
 prompt_setprompt({buf}, {text}) none	set prompt text
-prompt_setcallback({buf}, {expr}) none	set prompt callback function
 pumvisible()			Number	whether popup menu is visible
 pyeval({expr})			any	evaluate |Python| expression
 py3eval({expr})			any	evaluate |python3| expression
@@ -6506,17 +6507,11 @@ printf({fmt}, {expr1} ...)				*printf()*
 		arguments an error is given.  Up to 18 arguments can be used.
 
 
-prompt_setprompt({buf}, {text})				*prompt_setprompt()*
-		Set prompt for buffer {buf} to {text}.  You most likely want
-		{text} to end in a space.
-		The result is only visible if {buf} has 'buftype' set to
-		"prompt".  Example: >
-			call prompt_setprompt(bufnr(''), 'command: ')
-
-
 prompt_setcallback({buf}, {expr})			*prompt_setcallback()*
-		Set prompt callback for buffer {buf} to {expr}.  This has only
+		Set prompt callback for buffer {buf} to {expr}.  When {expr}
+		is an empty string the callback is removed.  This has only
 		effect if {buf} has 'buftype' set to "prompt".
+
 		The callback is invoked when pressing Enter.  The current
 		buffer will always be the prompt buffer.  A new line for a
 		prompt is added before invoking the callback, thus the prompt
@@ -6541,6 +6536,22 @@ prompt_setcallback({buf}, {expr})			*pro
 		     endif
 		   endfunc
 
+prompt_setinterrupt({buf}, {expr})			*prompt_setinterrupt()*
+		Set a callback for buffer {buf} to {expr}.  When {expr} is an
+		empty string the callback is removed.  This has only effect if
+		{buf} has 'buftype' set to "prompt".
+
+		This callback will be invoked when pressing CTRL-C in Insert
+		mode.  Without setting a callback Vim will exit Insert mode,
+		as in any buffer.
+
+prompt_setprompt({buf}, {text})				*prompt_setprompt()*
+		Set prompt for buffer {buf} to {text}.  You most likely want
+		{text} to end in a space.
+		The result is only visible if {buf} has 'buftype' set to
+		"prompt".  Example: >
+			call prompt_setprompt(bufnr(''), 'command: ')
+
 
 pumvisible()						*pumvisible()*
 		Returns non-zero when the popup menu is visible, zero
@@ -8563,7 +8574,9 @@ term_start({cmd}, {options})				*term_st
 				     instead of using 'termwinsize'
 		   "term_cols"	     horizontal size to use for the terminal,
 				     instead of using 'termwinsize'
-		   "vertical"	     split the window vertically
+		   "vertical"	     split the window vertically; note that
+				     other window position can be defined with
+				     command modifiers, such as |:belowright|.
 		   "curwin"	     use the current window, do not split the
 				     window; fails if the current buffer
 				     cannot be |abandon|ed
@@ -9392,11 +9405,12 @@ vtp			Compiled for vcon support |+vtp| (
 			out if it works in the current console).
 wildignore		Compiled with 'wildignore' option.
 wildmenu		Compiled with 'wildmenu' option.
+win16			old version for MS-Windows 3.1 (always False)
 win32			Win32 version of Vim (MS-Windows 95 and later, 32 or
 			64 bits)
 win32unix		Win32 version of Vim, using Unix files (Cygwin)
 win64			Win64 version of Vim (MS-Windows 64 bit).
-win95			Win32 version for MS-Windows 95/98/ME.
+win95			Win32 version for MS-Windows 95/98/ME (always False)
 winaltkeys		Compiled with 'winaltkeys' option.
 windows			Compiled with support for more than one window.
 writebackup		Compiled with 'writebackup' default on.
--- a/src/channel.c
+++ b/src/channel.c
@@ -5856,7 +5856,7 @@ invoke_prompt_callback(void)
     curwin->w_cursor.lnum = lnum + 1;
     curwin->w_cursor.col = 0;
 
-    if (curbuf->b_prompt_callback == NULL)
+    if (curbuf->b_prompt_callback == NULL || *curbuf->b_prompt_callback == NUL)
 	return;
     text = ml_get(lnum);
     prompt = prompt_text();
@@ -5874,4 +5874,28 @@ invoke_prompt_callback(void)
     clear_tv(&rettv);
 }
 
+/*
+ * Return TRUE when the interrupt callback was invoked.
+ */
+    int
+invoke_prompt_interrupt(void)
+{
+    typval_T	rettv;
+    int		dummy;
+    typval_T	argv[1];
+
+    if (curbuf->b_prompt_interrupt == NULL
+					|| *curbuf->b_prompt_interrupt == NUL)
+	return FALSE;
+    argv[0].v_type = VAR_UNKNOWN;
+
+    got_int = FALSE; // don't skip executing commands
+    call_func(curbuf->b_prompt_interrupt,
+	      (int)STRLEN(curbuf->b_prompt_interrupt),
+	      &rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE,
+	      curbuf->b_prompt_int_partial, NULL);
+    clear_tv(&rettv);
+    return TRUE;
+}
+
 #endif /* FEAT_JOB_CHANNEL */
--- a/src/edit.c
+++ b/src/edit.c
@@ -1016,6 +1016,19 @@ edit(
 		goto doESCkey;
 	    }
 #endif
+#ifdef FEAT_JOB_CHANNEL
+	    if (c == Ctrl_C && bt_prompt(curbuf))
+	    {
+		if (invoke_prompt_interrupt())
+		{
+		    if (!bt_prompt(curbuf))
+			// buffer changed to a non-prompt buffer, get out of
+			// Insert mode
+			goto doESCkey;
+		    break;
+		}
+	    }
+#endif
 
 #ifdef UNIX
 do_intr:
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -298,6 +298,7 @@ static void f_prevnonblank(typval_T *arg
 static void f_printf(typval_T *argvars, typval_T *rettv);
 #ifdef FEAT_JOB_CHANNEL
 static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv);
+static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv);
 static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv);
 #endif
 static void f_pumvisible(typval_T *argvars, typval_T *rettv);
@@ -754,6 +755,7 @@ static struct fst
     {"printf",		1, 19, f_printf},
 #ifdef FEAT_JOB_CHANNEL
     {"prompt_setcallback", 2, 2, f_prompt_setcallback},
+    {"prompt_setinterrupt", 2, 2, f_prompt_setinterrupt},
     {"prompt_setprompt", 2, 2, f_prompt_setprompt},
 #endif
     {"pumvisible",	0, 0, f_pumvisible},
@@ -8622,6 +8624,35 @@ f_prompt_setcallback(typval_T *argvars, 
 }
 
 /*
+ * "prompt_setinterrupt({buffer}, {callback})" function
+ */
+    static void
+f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
+{
+    buf_T	*buf;
+    char_u	*callback;
+    partial_T	*partial;
+
+    if (check_secure())
+	return;
+    buf = get_buf_tv(&argvars[0], FALSE);
+    if (buf == NULL)
+	return;
+
+    callback = get_callback(&argvars[1], &partial);
+    if (callback == NULL)
+	return;
+
+    free_callback(buf->b_prompt_interrupt, buf->b_prompt_int_partial);
+    if (partial == NULL)
+	buf->b_prompt_interrupt = vim_strsave(callback);
+    else
+	/* pointer into the partial */
+	buf->b_prompt_interrupt = callback;
+    buf->b_prompt_int_partial = partial;
+}
+
+/*
  * "prompt_setprompt({buffer}, {text})" function
  */
     static void
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -72,4 +72,5 @@ void job_info(job_T *job, dict_T *dict);
 void job_info_all(list_T *l);
 int job_stop(job_T *job, typval_T *argvars, char *type);
 void invoke_prompt_callback(void);
+int invoke_prompt_interrupt(void);
 /* vim: set ft=c : */
--- 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 */
 /**/
+    69,
+/**/
     68,
 /**/
     67,