diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-08-21 10:45:25 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-08-21 14:16:15 +0800 |
commit | ab45d5bf6d46abd9b29389dee6689044fd63e225 (patch) | |
tree | 02f0cf7db2832114639613ead497b45a409deb40 /src/nvim/normal.c | |
parent | 91d8f2ac534a51859c0e3c6562d07c94b27f4478 (diff) | |
download | rneovim-ab45d5bf6d46abd9b29389dee6689044fd63e225.tar.gz rneovim-ab45d5bf6d46abd9b29389dee6689044fd63e225.tar.bz2 rneovim-ab45d5bf6d46abd9b29389dee6689044fd63e225.zip |
vim-patch:8.1.2044: no easy way to process postponed work
Problem: No easy way to process postponed work. (Paul Jolly)
Solution: Add the SafeState autocommand event.
https://github.com/vim/vim/commit/8aeec40207b5adcd3a155277dc4f29189343b963
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src/nvim/normal.c')
-rw-r--r-- | src/nvim/normal.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c index e72a0fe385..253a3f288e 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -482,6 +482,40 @@ bool check_text_or_curbuf_locked(oparg_T *oap) return true; } +static bool was_safe = false; +static int not_safe_now = 0; + +/// 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 + && !global_busy; + + if (is_safe) { + apply_autocmds(EVENT_SAFESTATE, NULL, NULL, false, curbuf); + } + was_safe = is_safe; +} + +/// Entering a not-safe state. +void enter_unsafe_state(void) +{ + not_safe_now++; +} + +/// Leaving a not-safe state. Trigger SafeState if we were in a safe state +/// before first calling enter_not_safe_state(). +void leave_unsafe_state(void) +{ + not_safe_now--; + if (not_safe_now == 0 && was_safe) { + apply_autocmds(EVENT_SAFESTATE, NULL, NULL, false, curbuf); + } +} + /// Normal state entry point. This is called on: /// /// - Startup, In this case the function never returns. @@ -1295,6 +1329,18 @@ static void normal_check_buffer_modified(NormalState *s) } } +/// If nothing is pending and we are going to wait for the user to +/// type a character, trigger SafeState. +static void normal_check_safe_state(NormalState *s) +{ + may_trigger_safestate(!finish_op + && s->oa.prev_opcount > 0 + && s->oa.prev_count0 == 0 + && s->oa.op_type == OP_NOP + && s->oa.regname == NUL + && restart_edit == 0); +} + static void normal_check_folds(NormalState *s) { // Include a closed fold completely in the Visual area. @@ -1387,6 +1433,9 @@ static int normal_check(VimState *state) } quit_more = false; + // it's not safe unless normal_check_safe_state() is called + was_safe = false; + // 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, // update cursor and redraw. @@ -1403,6 +1452,7 @@ static int normal_check(VimState *state) normal_check_text_changed(s); normal_check_window_scrolled(s); normal_check_buffer_modified(s); + normal_check_safe_state(s); // Updating diffs from changed() does not always work properly, // esp. updating folds. Do an update just before redrawing if |