diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-09-18 21:15:31 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-09-18 21:15:31 +0200 |
commit | d103ee78432f9036d243b18dd5aac1263d3b7dc9 (patch) | |
tree | 5b63ac38b27bdf3459ef73f82eff2b2376da41c1 /src/main.c | |
parent | 7a9bd7c1e0ce1baf5a02daf36eeae3638aa315c7 (diff) | |
download | vim-git-d103ee78432f9036d243b18dd5aac1263d3b7dc9.tar.gz |
patch 8.1.2053: SafeStateAgain not triggered if callback uses feedkeys()v8.1.2053
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().
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/src/main.c b/src/main.c index 52bbafe6c..8c56c17b5 100644 --- a/src/main.c +++ b/src/main.c @@ -1049,24 +1049,33 @@ op_pending(void) } /* + * 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. */ 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 } |