mirror of
https://github.com/vim/vim.git
synced 2025-09-30 04:44:14 -04:00
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().
This commit is contained in:
49
src/main.c
49
src/main.c
@@ -1048,6 +1048,19 @@ op_pending(void)
|
||||
&& current_oap->regname == NUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return whether currently it is safe, assuming it was safe before (high level
|
||||
* state didn't change).
|
||||
*/
|
||||
static int
|
||||
is_safe_now(void)
|
||||
{
|
||||
return stuff_empty()
|
||||
&& typebuf.tb_len == 0
|
||||
&& scriptin[curscript] == NULL
|
||||
&& !global_busy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Trigger SafeState if currently in s safe state, that is "safe" is TRUE and
|
||||
* there is no typeahead.
|
||||
@@ -1055,18 +1068,14 @@ op_pending(void)
|
||||
void
|
||||
may_trigger_safestate(int safe)
|
||||
{
|
||||
int is_safe = safe
|
||||
&& stuff_empty()
|
||||
&& typebuf.tb_len == 0
|
||||
&& scriptin[curscript] == NULL
|
||||
&& !global_busy;
|
||||
int is_safe = safe && is_safe_now();
|
||||
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
if (was_safe != is_safe)
|
||||
// Only log when the state changes, otherwise it happens at nearly
|
||||
// every key stroke.
|
||||
ch_log(NULL, is_safe ? "Start triggering SafeState"
|
||||
: "Stop triggering SafeState");
|
||||
ch_log(NULL, is_safe ? "SafeState: Start triggering"
|
||||
: "SafeState: Stop triggering");
|
||||
#endif
|
||||
if (is_safe)
|
||||
apply_autocmds(EVENT_SAFESTATE, NULL, NULL, FALSE, curbuf);
|
||||
@@ -1079,15 +1088,21 @@ may_trigger_safestate(int safe)
|
||||
* may_trigger_safestate().
|
||||
*/
|
||||
void
|
||||
state_no_longer_safe(void)
|
||||
state_no_longer_safe(char *reason UNUSED)
|
||||
{
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
if (was_safe)
|
||||
ch_log(NULL, "safe state reset");
|
||||
ch_log(NULL, "SafeState: reset: %s", reason);
|
||||
#endif
|
||||
was_safe = FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
get_was_safe_state(void)
|
||||
{
|
||||
return was_safe;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoked when leaving code that invokes callbacks. Then trigger
|
||||
* SafeStateAgain, if it was safe when starting to wait for a character.
|
||||
@@ -1095,16 +1110,28 @@ state_no_longer_safe(void)
|
||||
void
|
||||
may_trigger_safestateagain(void)
|
||||
{
|
||||
if (!was_safe)
|
||||
{
|
||||
// If the safe state was reset in state_no_longer_safe(), e.g. because
|
||||
// of calling feedkeys(), we check if it's now safe again (all keys
|
||||
// were consumed).
|
||||
was_safe = is_safe_now();
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
if (was_safe)
|
||||
ch_log(NULL, "SafeState: undo reset");
|
||||
#endif
|
||||
}
|
||||
if (was_safe)
|
||||
{
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
ch_log(NULL, "Leaving unsafe area, triggering SafeStateAgain");
|
||||
ch_log(NULL, "SafeState: back to waiting, triggering SafeStateAgain");
|
||||
#endif
|
||||
apply_autocmds(EVENT_SAFESTATEAGAIN, NULL, NULL, FALSE, curbuf);
|
||||
}
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
else
|
||||
ch_log(NULL, "Leaving unsafe area, not triggering SafeStateAgain");
|
||||
ch_log(NULL,
|
||||
"SafeState: back to waiting, not triggering SafeStateAgain");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user