diff options
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r-- | src/nvim/ops.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 766b5720d9..3163132b8a 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -72,6 +72,12 @@ static yankreg_T y_regs[NUM_REGISTERS]; static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */ static bool clipboard_didwarn_unnamed = false; + +// for behavior between start_global_changes() and end_global_changes()) +static bool clipboard_delay_update = false; // delay clipboard update +static int global_change_count = 0; // if set, inside global changes +static bool clipboard_needs_update = false; // the clipboard was updated + /* * structure used by block_prep, op_delete and op_yank for blockwise operators * also op_change, op_shift, op_insert, op_replace - AKelly @@ -5244,7 +5250,7 @@ void cursor_pos_info(void) int get_default_register_name(void) { int name = NUL; - adjust_clipboard_name(&name, true); + adjust_clipboard_name(&name, true, false); return name; } @@ -5258,7 +5264,7 @@ int get_default_register_name(void) /// /// @returns the yankreg that should be written into, or `NULL` /// if the register isn't a clipboard or provider isn't available. -static yankreg_T *adjust_clipboard_name(int *name, bool quiet) +static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) { if (*name == '*' || *name == '+') { if(!eval_has_provider("clipboard")) { @@ -5276,6 +5282,14 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet) } return NULL; } + if (writing && clipboard_delay_update) { + clipboard_needs_update = true; + return NULL; + } else if (!writing && clipboard_needs_update) { + // use the internal value + return NULL; + } + yankreg_T *target; if (cb_flags & CB_UNNAMEDPLUS) { *name = cb_flags & CB_UNNAMED ? '"': '+'; @@ -5295,7 +5309,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet) // show message on error bool errmsg = true; - yankreg_T *reg = adjust_clipboard_name(&name, quiet); + yankreg_T *reg = adjust_clipboard_name(&name, quiet, false); if (reg == NULL) { return false; } @@ -5406,7 +5420,7 @@ err: static void set_clipboard(int name, yankreg_T *reg) { - if(!adjust_clipboard_name(&name, false)) { + if (!adjust_clipboard_name(&name, false, true)) { return; } @@ -5440,3 +5454,27 @@ static void set_clipboard(int name, yankreg_T *reg) (void)eval_call_provider("clipboard", "set", args); } + +/// Avoid clipboard (slow) during batch operations (:global). +void start_global_changes(void) +{ + if (++global_change_count > 1) { + return; + } + clipboard_delay_update = true; + clipboard_needs_update = false; +} + +/// Update the clipboard after :global changes finished. +void end_global_changes(void) +{ + if (--global_change_count > 0) { + // recursive + return; + } + clipboard_delay_update = false; + if (clipboard_needs_update) { + set_clipboard(NUL, y_previous); + clipboard_needs_update = false; + } +} |