mirror of
https://github.com/neovim/neovim.git
synced 2025-09-17 16:58:17 +00:00
vim-patch:8.1.2053: SafeStateAgain not triggered if callback uses feedkeys()
Problem: SafeStateAgain not triggered if callback uses feedkeys().
Solution: Check for safe state in the input loop. Make log messages easier
to find. Add 'S' flag to state().
d103ee7843
Include misc1.c change from patch 8.1.2062.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
7
runtime/doc/builtin.txt
generated
7
runtime/doc/builtin.txt
generated
@@ -7385,13 +7385,16 @@ state([{what}]) *state()*
|
|||||||
added. E.g, this checks if the screen has scrolled: >vim
|
added. E.g, this checks if the screen has scrolled: >vim
|
||||||
if state('s') != ''
|
if state('s') != ''
|
||||||
|
|
||||||
These characters indicate the state:
|
These characters indicate the state, generally indicating that
|
||||||
|
something is busy:
|
||||||
m halfway a mapping, :normal command, feedkeys() or
|
m halfway a mapping, :normal command, feedkeys() or
|
||||||
stuffed command
|
stuffed command
|
||||||
o operator pending or waiting for a command argument
|
o operator pending or waiting for a command argument
|
||||||
a Insert mode autocomplete active
|
a Insert mode autocomplete active
|
||||||
x executing an autocommand
|
x executing an autocommand
|
||||||
c callback invoked (repeats for recursiveness up to "ccc")
|
S not triggering SafeState
|
||||||
|
c callback invoked, including timer (repeats for
|
||||||
|
recursiveness up to "ccc")
|
||||||
s screen has scrolled for messages
|
s screen has scrolled for messages
|
||||||
|
|
||||||
stdioopen({opts}) *stdioopen()*
|
stdioopen({opts}) *stdioopen()*
|
||||||
|
7
runtime/lua/vim/_meta/vimfn.lua
generated
7
runtime/lua/vim/_meta/vimfn.lua
generated
@@ -8760,13 +8760,16 @@ function vim.fn.srand(expr) end
|
|||||||
--- added. E.g, this checks if the screen has scrolled: >vim
|
--- added. E.g, this checks if the screen has scrolled: >vim
|
||||||
--- if state('s') != ''
|
--- if state('s') != ''
|
||||||
---
|
---
|
||||||
--- These characters indicate the state:
|
--- These characters indicate the state, generally indicating that
|
||||||
|
--- something is busy:
|
||||||
--- m halfway a mapping, :normal command, feedkeys() or
|
--- m halfway a mapping, :normal command, feedkeys() or
|
||||||
--- stuffed command
|
--- stuffed command
|
||||||
--- o operator pending or waiting for a command argument
|
--- o operator pending or waiting for a command argument
|
||||||
--- a Insert mode autocomplete active
|
--- a Insert mode autocomplete active
|
||||||
--- x executing an autocommand
|
--- x executing an autocommand
|
||||||
--- c callback invoked (repeats for recursiveness up to "ccc")
|
--- S not triggering SafeState
|
||||||
|
--- c callback invoked, including timer (repeats for
|
||||||
|
--- recursiveness up to "ccc")
|
||||||
--- s screen has scrolled for messages
|
--- s screen has scrolled for messages
|
||||||
---
|
---
|
||||||
--- @param what? string
|
--- @param what? string
|
||||||
|
@@ -10471,13 +10471,16 @@ M.funcs = {
|
|||||||
added. E.g, this checks if the screen has scrolled: >vim
|
added. E.g, this checks if the screen has scrolled: >vim
|
||||||
if state('s') != ''
|
if state('s') != ''
|
||||||
|
|
||||||
These characters indicate the state:
|
These characters indicate the state, generally indicating that
|
||||||
|
something is busy:
|
||||||
m halfway a mapping, :normal command, feedkeys() or
|
m halfway a mapping, :normal command, feedkeys() or
|
||||||
stuffed command
|
stuffed command
|
||||||
o operator pending or waiting for a command argument
|
o operator pending or waiting for a command argument
|
||||||
a Insert mode autocomplete active
|
a Insert mode autocomplete active
|
||||||
x executing an autocommand
|
x executing an autocommand
|
||||||
c callback invoked (repeats for recursiveness up to "ccc")
|
S not triggering SafeState
|
||||||
|
c callback invoked, including timer (repeats for
|
||||||
|
recursiveness up to "ccc")
|
||||||
s screen has scrolled for messages
|
s screen has scrolled for messages
|
||||||
]=],
|
]=],
|
||||||
name = 'state',
|
name = 'state',
|
||||||
|
@@ -4955,6 +4955,9 @@ static void f_state(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
if (!ctrl_x_mode_none()) {
|
if (!ctrl_x_mode_none()) {
|
||||||
may_add_state_char(&ga, include, 'a');
|
may_add_state_char(&ga, include, 'a');
|
||||||
}
|
}
|
||||||
|
if (!get_was_safe_state()) {
|
||||||
|
may_add_state_char(&ga, include, 'S');
|
||||||
|
}
|
||||||
for (int i = 0; i < get_callback_depth() && i < 3; i++) {
|
for (int i = 0; i < get_callback_depth() && i < 3; i++) {
|
||||||
may_add_state_char(&ga, include, 'c');
|
may_add_state_char(&ga, include, 'c');
|
||||||
}
|
}
|
||||||
|
@@ -885,7 +885,7 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent)
|
|||||||
if (++typebuf.tb_change_cnt == 0) {
|
if (++typebuf.tb_change_cnt == 0) {
|
||||||
typebuf.tb_change_cnt = 1;
|
typebuf.tb_change_cnt = 1;
|
||||||
}
|
}
|
||||||
state_no_longer_safe();
|
state_no_longer_safe("ins_typebuf()");
|
||||||
|
|
||||||
addlen = (int)strlen(str);
|
addlen = (int)strlen(str);
|
||||||
|
|
||||||
@@ -1629,7 +1629,7 @@ int vgetc(void)
|
|||||||
// Need to process the character before we know it's safe to do something
|
// Need to process the character before we know it's safe to do something
|
||||||
// else.
|
// else.
|
||||||
if (c != K_IGNORE) {
|
if (c != K_IGNORE) {
|
||||||
state_no_longer_safe();
|
state_no_longer_safe("key typed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
@@ -1412,7 +1412,7 @@ static int normal_check(VimState *state)
|
|||||||
quit_more = false;
|
quit_more = false;
|
||||||
|
|
||||||
// it's not safe unless normal_check_safe_state() is called
|
// it's not safe unless normal_check_safe_state() is called
|
||||||
state_no_longer_safe();
|
state_no_longer_safe(NULL);
|
||||||
|
|
||||||
// If skip redraw is set (for ":" in wait_return()), don't redraw now.
|
// If skip redraw is set (for ":" in wait_return()), don't redraw now.
|
||||||
// If there is nothing in the stuff_buffer or do_redraw is true,
|
// If there is nothing in the stuff_buffer or do_redraw is true,
|
||||||
|
@@ -272,20 +272,26 @@ void may_trigger_modechanged(void)
|
|||||||
/// When true in a safe state when starting to wait for a character.
|
/// When true in a safe state when starting to wait for a character.
|
||||||
static bool was_safe = false;
|
static bool was_safe = false;
|
||||||
|
|
||||||
|
/// Return whether currently it is safe, assuming it was safe before (high level
|
||||||
|
/// state didn't change).
|
||||||
|
static bool is_safe_now(void)
|
||||||
|
{
|
||||||
|
return stuff_empty()
|
||||||
|
&& typebuf.tb_len == 0
|
||||||
|
&& !using_script()
|
||||||
|
&& !global_busy;
|
||||||
|
}
|
||||||
|
|
||||||
/// Trigger SafeState if currently in s safe state, that is "safe" is TRUE and
|
/// Trigger SafeState if currently in s safe state, that is "safe" is TRUE and
|
||||||
/// there is no typeahead.
|
/// there is no typeahead.
|
||||||
void may_trigger_safestate(bool safe)
|
void may_trigger_safestate(bool safe)
|
||||||
{
|
{
|
||||||
bool is_safe = safe
|
bool is_safe = safe && is_safe_now();
|
||||||
&& stuff_empty()
|
|
||||||
&& typebuf.tb_len == 0
|
|
||||||
&& !using_script()
|
|
||||||
&& !global_busy;
|
|
||||||
|
|
||||||
if (was_safe != is_safe) {
|
if (was_safe != is_safe) {
|
||||||
// Only log when the state changes, otherwise it happens at nearly
|
// Only log when the state changes, otherwise it happens at nearly
|
||||||
// every key stroke.
|
// every key stroke.
|
||||||
DLOG(is_safe ? "Start triggering SafeState" : "Stop triggering SafeState");
|
DLOG(is_safe ? "SafeState: Start triggering" : "SafeState: Stop triggering");
|
||||||
}
|
}
|
||||||
if (is_safe) {
|
if (is_safe) {
|
||||||
apply_autocmds(EVENT_SAFESTATE, NULL, NULL, false, curbuf);
|
apply_autocmds(EVENT_SAFESTATE, NULL, NULL, false, curbuf);
|
||||||
@@ -296,10 +302,15 @@ void may_trigger_safestate(bool safe)
|
|||||||
/// Something changed which causes the state possibly to be unsafe, e.g. a
|
/// Something changed which causes the state possibly to be unsafe, e.g. a
|
||||||
/// character was typed. It will remain unsafe until the next call to
|
/// character was typed. It will remain unsafe until the next call to
|
||||||
/// may_trigger_safestate().
|
/// may_trigger_safestate().
|
||||||
void state_no_longer_safe(void)
|
void state_no_longer_safe(const char *reason)
|
||||||
{
|
{
|
||||||
if (was_safe) {
|
if (was_safe && reason != NULL) {
|
||||||
DLOG("safe state reset");
|
DLOG("SafeState reset: %s", reason);
|
||||||
}
|
}
|
||||||
was_safe = false;
|
was_safe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_was_safe_state(void)
|
||||||
|
{
|
||||||
|
return was_safe;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user