diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
commit | 1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch) | |
tree | cd08258054db80bb9a11b1061bb091c70b76926a /src/nvim/state.c | |
parent | eaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-aucmd_textputpost.tar.gz rneovim-aucmd_textputpost.tar.bz2 rneovim-aucmd_textputpost.zip |
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'src/nvim/state.c')
-rw-r--r-- | src/nvim/state.c | 81 |
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; +} |