]> granicus.if.org Git - vim/commitdiff
patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer v8.1.0069
authorBram Moolenaar <Bram@vim.org>
Sun, 17 Jun 2018 17:36:33 +0000 (19:36 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 17 Jun 2018 17:36:33 +0000 (19:36 +0200)
Problem:    Cannot handle pressing CTRL-C in a prompt buffer.
Solution:   Add prompt_setinterrupt().

runtime/doc/eval.txt
src/channel.c
src/edit.c
src/evalfunc.c
src/proto/channel.pro
src/version.c

index ead6b89281d91470154395c207330ca8a1583f54..36e4f22bade24b39264524243ce50213b101780f 100644 (file)
@@ -2297,8 +2297,9 @@ pow({x}, {y})                     Float   {x} to the power of {y}
 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_setprompt({buf}, {text}) none   set prompt text
 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
 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})                        *prompt_setcallback()*
                     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_start()*
                                     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| (check vcon to find
                        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.
index d654dc06d30812ae2fb3efb469928ca2747ddc71..1363ee92991f06db91b0263d7e7dd6336c70678d 100644 (file)
@@ -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 */
index 3204ec31a7c2cf9921240e29a15a828501ee2d18..6a636b9e1282836a55aa9f0ba96318a69b3e06c4 100644 (file)
@@ -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:
index 4960203978b36c15c6e39250cb73e59bffe5ef57..3cb66f3bbc2534087ba2ad105d36a46307abfb2c 100644 (file)
@@ -298,6 +298,7 @@ static void f_prevnonblank(typval_T *argvars, typval_T *rettv);
 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},
@@ -8621,6 +8623,35 @@ f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
     buf->b_prompt_partial = partial;
 }
 
+/*
+ * "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
  */
index 5326276ef1802836cc2cce57cfc716777a7eab41..57b958ae105016b01d706ee61a410a97c5bb0a6d 100644 (file)
@@ -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 : */
index e55be5206bb0ba4070945fcddc1bc3fd95685886..1f462b31b4d883467ff680a873057cfa9275f27d 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    69,
 /**/
     68,
 /**/