aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/state.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
commit339e2d15cc26fe86988ea06468d912a46c8d6f29 (patch)
treea6167fc8fcfc6ae2dc102f57b2473858eac34063 /src/nvim/state.c
parent067dc73729267c0262438a6fdd66e586f8496946 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.gz
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.bz2
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.zip
Merge remote-tracking branch 'upstream/master' into fix_repeatcmdline
Diffstat (limited to 'src/nvim/state.c')
-rw-r--r--src/nvim/state.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/src/nvim/state.c b/src/nvim/state.c
index 9ba5f81776..900eac0826 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -1,35 +1,29 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
#include <stdbool.h>
-#include <stddef.h>
#include <string.h>
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
-#include "nvim/buffer_defs.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/eval/typval_defs.h"
#include "nvim/event/defs.h"
-#include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h"
+#include "nvim/ex_getln.h"
#include "nvim/getchar.h"
#include "nvim/globals.h"
#include "nvim/insexpand.h"
#include "nvim/keycodes.h"
#include "nvim/log.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/main.h"
+#include "nvim/memory.h"
#include "nvim/option.h"
+#include "nvim/option_vars.h"
#include "nvim/os/input.h"
-#include "nvim/screen.h"
#include "nvim/state.h"
#include "nvim/strings.h"
-#include "nvim/types.h"
+#include "nvim/types_defs.h"
#include "nvim/ui.h"
-#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "state.c.generated.h" // IWYU pragma: export
@@ -37,7 +31,7 @@
void state_enter(VimState *s)
{
- for (;;) {
+ while (true) {
int check_result = s->check ? s->check(s) : 1;
if (!check_result) {
@@ -62,6 +56,8 @@ getkey:
if (vpeekc() != NUL || typebuf.tb_len > 0) {
key = safe_vgetc();
} else if (!multiqueue_empty(main_loop.events)) {
+ // No input available and processing events may take time, flush now.
+ ui_flush();
// Event was made available after the last multiqueue_process_events call
key = K_EVENT;
} else {
@@ -71,7 +67,7 @@ getkey:
update_screen();
setcursor(); // put cursor back where it belongs
}
- // Flush screen updates before blocking
+ // Flush screen updates before blocking.
ui_flush();
// Call `os_inchar` directly to block for events or user input without
// consuming anything from `input_buffer`(os/input.c) or calling the
@@ -92,8 +88,9 @@ getkey:
may_sync_undo();
}
-#if MIN_LOG_LEVEL <= LOGLVL_DBG
- log_key(LOGLVL_DBG, key);
+#ifdef NVIM_LOG_DEBUG
+ char *keyname = key == K_EVENT ? "K_EVENT" : get_special_key_name(key, mod_mask);
+ DLOG("input: %s", keyname);
#endif
int execute_result = s->execute(s, key);
@@ -135,7 +132,7 @@ void state_handle_k_event(void)
/// Return true if in the current mode we need to use virtual.
bool virtual_active(void)
{
- unsigned int cur_ve_flags = get_ve_flags();
+ unsigned cur_ve_flags = get_ve_flags();
// While an operator is being executed we return "virtual_op", because
// VIsual_active has already been reset, thus we can't check for "block"
@@ -214,6 +211,9 @@ void get_mode(char *buf)
if (exmode_active) {
buf[i++] = 'v';
}
+ if ((State & MODE_CMDLINE) && cmdline_overstrike()) {
+ buf[i++] = 'r';
+ }
} else if (State & MODE_TERMINAL) {
buf[i++] = 't';
} else {
@@ -268,3 +268,50 @@ void may_trigger_modechanged(void)
restore_v_event(v_event, &save_v_event);
}
+
+/// 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
+ && !debug_mode;
+}
+
+/// 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 && 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 ? "SafeState: Start triggering" : "SafeState: Stop triggering");
+ }
+ if (is_safe) {
+ apply_autocmds(EVENT_SAFESTATE, NULL, NULL, false, curbuf);
+ }
+ was_safe = is_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(const char *reason)
+{
+ if (was_safe && reason != NULL) {
+ DLOG("SafeState reset: %s", reason);
+ }
+ was_safe = false;
+}
+
+bool get_was_safe_state(void)
+{
+ return was_safe;
+}