Skip to content


Browse files Browse the repository at this point in the history
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().
  • Loading branch information
brammool committed Jun 17, 2018
1 parent 2f82ca7 commit 0e5979a
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 13 deletions.
38 changes: 26 additions & 12 deletions runtime/doc/eval.txt
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -6541,6 +6536,22 @@ prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
26 changes: 25 additions & 1 deletion src/channel.c
Expand Up @@ -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)
text = ml_get(lnum);
prompt = prompt_text();
Expand All @@ -5874,4 +5874,28 @@ invoke_prompt_callback(void)

* Return TRUE when the interrupt callback was invoked.
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
&rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE,
curbuf->b_prompt_int_partial, NULL);
return TRUE;

#endif /* FEAT_JOB_CHANNEL */
13 changes: 13 additions & 0 deletions src/edit.c
Expand Up @@ -1016,6 +1016,19 @@ edit(
goto doESCkey;
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;

#ifdef UNIX
Expand Down
31 changes: 31 additions & 0 deletions src/evalfunc.c
Expand Up @@ -298,6 +298,7 @@ static void f_prevnonblank(typval_T *argvars, typval_T *rettv);
static void f_printf(typval_T *argvars, typval_T *rettv);
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);
static void f_pumvisible(typval_T *argvars, typval_T *rettv);
Expand Down Expand Up @@ -754,6 +755,7 @@ static struct fst
{"printf", 1, 19, f_printf},
{"prompt_setcallback", 2, 2, f_prompt_setcallback},
{"prompt_setinterrupt", 2, 2, f_prompt_setinterrupt},
{"prompt_setprompt", 2, 2, f_prompt_setprompt},
{"pumvisible", 0, 0, f_pumvisible},
Expand Down Expand Up @@ -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())
buf = get_buf_tv(&argvars[0], FALSE);
if (buf == NULL)

callback = get_callback(&argvars[1], &partial);
if (callback == NULL)

free_callback(buf->b_prompt_interrupt, buf->b_prompt_int_partial);
if (partial == NULL)
buf->b_prompt_interrupt = vim_strsave(callback);
/* pointer into the partial */
buf->b_prompt_interrupt = callback;
buf->b_prompt_int_partial = partial;

* "prompt_setprompt({buffer}, {text})" function
Expand Down
1 change: 1 addition & 0 deletions src/proto/
Expand Up @@ -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 : */
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -761,6 +761,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
Expand Down

0 comments on commit 0e5979a

Please sign in to comment.