vim-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().
0e5979a6d4
This commit is contained in:
erw7 2019-05-23 06:38:02 +09:00
parent 783aecd501
commit fe395ae210
6 changed files with 77 additions and 10 deletions

View File

@ -2281,8 +2281,9 @@ pow({x}, {y}) Float {x} to the power of {y}
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum} prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
printf({fmt}, {expr1}...) String format text printf({fmt}, {expr1}...) String format text
prompt_addtext({buf}, {expr}) none add text to a prompt buffer 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_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
pum_getpos() Dict position and size of pum if visible pum_getpos() Dict position and size of pum if visible
pumvisible() Number whether popup menu is visible pumvisible() Number whether popup menu is visible
pyeval({expr}) any evaluate |Python| expression pyeval({expr}) any evaluate |Python| expression
@ -6544,17 +6545,11 @@ printf({fmt}, {expr1} ...) *printf()*
of "%" items. If there are not sufficient or too many of "%" items. If there are not sufficient or too many
arguments an error is given. Up to 18 arguments can be used. 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()* 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". effect if {buf} has 'buftype' set to "prompt".
The callback is invoked when pressing Enter. The current The callback is invoked when pressing Enter. The current
buffer will always be the prompt buffer. A new line for a buffer will always be the prompt buffer. A new line for a
prompt is added before invoking the callback, thus the prompt prompt is added before invoking the callback, thus the prompt
@ -6579,6 +6574,22 @@ prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
endif endif
endfunc 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: ')
pum_getpos() *pum_getpos()* pum_getpos() *pum_getpos()*
If the popup menu (see |ins-completion-menu|) is not visible, If the popup menu (see |ins-completion-menu|) is not visible,
returns an empty |Dictionary|, otherwise, returns a returns an empty |Dictionary|, otherwise, returns a
@ -6591,6 +6602,7 @@ pum_getpos() *pum_getpos()*
scrollbar |TRUE| if visible scrollbar |TRUE| if visible
The values are the same as in |v:event| during |CompleteChanged|. The values are the same as in |v:event| during |CompleteChanged|.
pumvisible() *pumvisible()* pumvisible() *pumvisible()*
Returns non-zero when the popup menu is visible, zero Returns non-zero when the popup menu is visible, zero
otherwise. See |ins-completion-menu|. otherwise. See |ins-completion-menu|.

View File

@ -765,6 +765,7 @@ static void free_buffer(buf_T *buf)
tv_dict_unref(buf->additional_data); tv_dict_unref(buf->additional_data);
xfree(buf->b_prompt_text); xfree(buf->b_prompt_text);
callback_free(&buf->b_prompt_callback); callback_free(&buf->b_prompt_callback);
callback_free(&buf->b_prompt_interrupt);
clear_fmark(&buf->b_last_cursor); clear_fmark(&buf->b_last_cursor);
clear_fmark(&buf->b_last_insert); clear_fmark(&buf->b_last_insert);
clear_fmark(&buf->b_last_change); clear_fmark(&buf->b_last_change);
@ -1879,6 +1880,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
} }
buf->b_prompt_callback.type = kCallbackNone; buf->b_prompt_callback.type = kCallbackNone;
buf->b_prompt_interrupt.type = kCallbackNone;
buf->b_prompt_text = NULL; buf->b_prompt_text = NULL;
return buf; return buf;

View File

@ -823,6 +823,16 @@ static int insert_handle_key(InsertState *s)
s->nomove = true; s->nomove = true;
return 0; // exit insert mode return 0; // exit insert mode
} }
if (s->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
return 0;
}
break;
}
}
// when 'insertmode' set, and not halfway through a mapping, don't leave // when 'insertmode' set, and not halfway through a mapping, don't leave
// Insert mode // Insert mode

View File

@ -13718,3 +13718,20 @@ void invoke_prompt_callback(void)
tv_clear(&argv[0]); tv_clear(&argv[0]);
tv_clear(&rettv); tv_clear(&rettv);
} }
// Return true When the interrupt callback was invoked.
bool invoke_prompt_interrupt(void)
{
typval_T rettv;
typval_T argv[1];
if (curbuf->b_prompt_interrupt.type == kCallbackNone) {
return false;
}
argv[0].v_type = VAR_UNKNOWN;
got_int = false; // don't skip executing commands
callback_call(&curbuf->b_prompt_interrupt, 0, argv, &rettv);
tv_clear(&rettv);
return true;
}

View File

@ -244,6 +244,7 @@ return {
prevnonblank={args=1}, prevnonblank={args=1},
printf={args=varargs(1)}, printf={args=varargs(1)},
prompt_setcallback={args={2, 2}}, prompt_setcallback={args={2, 2}},
prompt_setinterrupt={args={2, 2}},
prompt_setprompt={args={2, 2}}, prompt_setprompt={args={2, 2}},
pum_getpos={}, pum_getpos={},
pumvisible={}, pumvisible={},

View File

@ -6101,6 +6101,31 @@ static void f_prompt_setcallback(typval_T *argvars,
buf->b_prompt_callback = prompt_callback; buf->b_prompt_callback = prompt_callback;
} }
// "prompt_setinterrupt({buffer}, {callback})" function
static void f_prompt_setinterrupt(typval_T *argvars,
typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
Callback interrupt_callback = { .type = kCallbackNone };
if (check_secure()) {
return;
}
buf = tv_get_buf(&argvars[0], false);
if (buf == NULL) {
return;
}
if (argvars[1].v_type != VAR_STRING || *argvars[1].vval.v_string != NUL) {
if (!callback_from_typval(&interrupt_callback, &argvars[1])) {
return;
}
}
callback_free(&buf->b_prompt_interrupt);
buf->b_prompt_interrupt= interrupt_callback;
}
// "prompt_setprompt({buffer}, {text})" function // "prompt_setprompt({buffer}, {text})" function
static void f_prompt_setprompt(typval_T *argvars, static void f_prompt_setprompt(typval_T *argvars,
typval_T *rettv, FunPtr fptr) typval_T *rettv, FunPtr fptr)