aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/builtin.txt7
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua7
-rw-r--r--src/nvim/eval.lua7
-rw-r--r--src/nvim/eval/funcs.c3
-rw-r--r--src/nvim/getchar.c4
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/state.c29
7 files changed, 41 insertions, 18 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index c57b8637e0..2ce66d8cc2 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -7385,13 +7385,16 @@ state([{what}]) *state()*
added. E.g, this checks if the screen has scrolled: >vim
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
stuffed command
o operator pending or waiting for a command argument
a Insert mode autocomplete active
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
stdioopen({opts}) *stdioopen()*
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index 4665f71052..70d1aa4a79 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -8760,13 +8760,16 @@ function vim.fn.srand(expr) end
--- added. E.g, this checks if the screen has scrolled: >vim
--- 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
--- stuffed command
--- o operator pending or waiting for a command argument
--- a Insert mode autocomplete active
--- 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
---
--- @param what? string
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index f244d26375..64b875c981 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -10471,13 +10471,16 @@ M.funcs = {
added. E.g, this checks if the screen has scrolled: >vim
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
stuffed command
o operator pending or waiting for a command argument
a Insert mode autocomplete active
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
]=],
name = 'state',
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index c47fd4cfcb..8c07623369 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -4955,6 +4955,9 @@ static void f_state(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
if (!ctrl_x_mode_none()) {
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++) {
may_add_state_char(&ga, include, 'c');
}
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 957f13b1da..d10e021f14 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -885,7 +885,7 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent)
if (++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
}
- state_no_longer_safe();
+ state_no_longer_safe("ins_typebuf()");
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
// else.
if (c != K_IGNORE) {
- state_no_longer_safe();
+ state_no_longer_safe("key typed");
}
return c;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 56bc75d658..40bef6b580 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1412,7 +1412,7 @@ static int normal_check(VimState *state)
quit_more = false;
// 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 there is nothing in the stuff_buffer or do_redraw is true,
diff --git a/src/nvim/state.c b/src/nvim/state.c
index 89e4b9cbbf..ccf2a81adb 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -272,20 +272,26 @@ void may_trigger_modechanged(void)
/// When true in a safe state when starting to wait for a character.
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
/// there is no typeahead.
void may_trigger_safestate(bool safe)
{
- bool is_safe = safe
- && stuff_empty()
- && typebuf.tb_len == 0
- && !using_script()
- && !global_busy;
+ bool is_safe = safe && is_safe_now();
if (was_safe != is_safe) {
// Only log when the state changes, otherwise it happens at nearly
// every key stroke.
- DLOG(is_safe ? "Start triggering SafeState" : "Stop triggering SafeState");
+ DLOG(is_safe ? "SafeState: Start triggering" : "SafeState: Stop triggering");
}
if (is_safe) {
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
/// character was typed. It will remain unsafe until the next call to
/// may_trigger_safestate().
-void state_no_longer_safe(void)
+void state_no_longer_safe(const char *reason)
{
- if (was_safe) {
- DLOG("safe state reset");
+ if (was_safe && reason != NULL) {
+ DLOG("SafeState reset: %s", reason);
}
was_safe = false;
}
+
+bool get_was_safe_state(void)
+{
+ return was_safe;
+}