diff options
-rw-r--r-- | src/nvim/ex_cmds.c | 5 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 4 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 4 | ||||
-rw-r--r-- | src/nvim/globals.h | 2 | ||||
-rw-r--r-- | src/nvim/ops.c | 46 | ||||
-rw-r--r-- | src/nvim/option.c | 8 | ||||
-rw-r--r-- | src/nvim/testdir/test_eval.in | 17 | ||||
-rw-r--r-- | src/nvim/testdir/test_eval.ok | bin | 10578 -> 11106 bytes | |||
-rw-r--r-- | src/nvim/version.c | 6 | ||||
-rw-r--r-- | test/functional/clipboard/clipboard_provider_spec.lua | 31 |
10 files changed, 106 insertions, 17 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 802a378b07..1e150444d0 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4433,8 +4433,11 @@ void ex_global(exarg_T *eap) smsg(_("Pattern found in every line: %s"), pat); else smsg(_("Pattern not found: %s"), pat); - } else + } else { + start_global_changes(); global_exe(cmd); + end_global_changes(); + } ml_clearmarked(); /* clear rest of the marks */ vim_regfree(regmatch.regprog); diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index efa18aa681..f172ea54c2 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -41,6 +41,7 @@ #include "nvim/memory.h" #include "nvim/move.h" #include "nvim/normal.h" +#include "nvim/ops.h" #include "nvim/option.h" #include "nvim/os_unix.h" #include "nvim/path.h" @@ -1838,6 +1839,8 @@ void ex_listdo(exarg_T *eap) * great speed improvement. */ save_ei = au_event_disable(",Syntax"); + start_global_changes(); + if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo || P_HID(curbuf) @@ -1988,6 +1991,7 @@ void ex_listdo(exarg_T *eap) apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, curbuf->b_fname, TRUE, curbuf); } + end_global_changes(); } /* diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3c57537397..d69d106dc6 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9380,6 +9380,8 @@ static void ex_folddo(exarg_T *eap) { linenr_T lnum; + start_global_changes(); + /* First set the marks for all lines closed/open. */ for (lnum = eap->line1; lnum <= eap->line2; ++lnum) if (hasFolding(lnum, NULL, NULL) == (eap->cmdidx == CMD_folddoclosed)) @@ -9388,6 +9390,8 @@ static void ex_folddo(exarg_T *eap) /* Execute the command on the marked lines. */ global_exe(eap->arg); ml_clearmarked(); /* clear rest of the marks */ + + end_global_changes(); } static void ex_terminal(exarg_T *eap) diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 5126195841..e5a993aa5a 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -519,8 +519,6 @@ EXTERN int sys_menu INIT(= FALSE); * ('lines' and 'rows') must not be changed. */ EXTERN int updating_screen INIT(= FALSE); - - /* * All windows are linked in a list. firstwin points to the first entry, * lastwin to the last entry (can be the same as firstwin) and curwin to the 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; + } +} diff --git a/src/nvim/option.c b/src/nvim/option.c index 38682f3142..ee50567728 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2583,11 +2583,11 @@ did_set_string_option ( else if (varp == &p_ead) { if (check_opt_strings(p_ead, p_ead_values, FALSE) != OK) errmsg = e_invarg; - } - else if (varp == &p_cb) { - if (opt_strings_flags(p_cb, p_cb_values, &cb_flags, TRUE) != OK) + } else if (varp == &p_cb) { // 'clipboard' + if (opt_strings_flags(p_cb, p_cb_values, &cb_flags, true) != OK) { errmsg = e_invarg; - } else if (varp == &(curwin->w_s->b_p_spl) + } + } else if (varp == &(curwin->w_s->b_p_spl) // 'spell' || varp == &(curwin->w_s->b_p_spf)) { // When 'spelllang' or 'spellfile' is set and there is a window for this // buffer in which 'spell' is set load the wordlists. diff --git a/src/nvim/testdir/test_eval.in b/src/nvim/testdir/test_eval.in index 95a59ee42a..328ee2e127 100644 --- a/src/nvim/testdir/test_eval.in +++ b/src/nvim/testdir/test_eval.in @@ -1,7 +1,6 @@ Test for various eval features. vim: set ft=vim : -Note: system clipboard support is not tested. I do not think anybody will thank -me for messing with clipboard. +Note: system clipboard is saved, changed and restored. STARTTEST :so small.vim @@ -122,7 +121,19 @@ call SetReg('/', ['abc/']) call SetReg('/', ["abc/\n"]) call SetReg('=', ['"abc/"']) call SetReg('=', ["\"abc/\n\""]) - +$put ='{{{1 System clipboard' +" Save and restore system clipboard. +" If no connection to X-Server is possible, test should succeed. +:let _clipreg = ['+', getreg('+'), getregtype('+')] +:let _clipopt = &cb +:let &cb='unnamedplus' +:1y +:AR + +:tabdo :windo :echo "hi" +:3y +:AR + +:let &cb=_clipopt +:call call('setreg', _clipreg) $put ='{{{1 Errors' call ErrExe('call setreg()') call ErrExe('call setreg(1)') diff --git a/src/nvim/testdir/test_eval.ok b/src/nvim/testdir/test_eval.ok Binary files differindex 061e0cfd2f..2cdb8f5da8 100644 --- a/src/nvim/testdir/test_eval.ok +++ b/src/nvim/testdir/test_eval.ok diff --git a/src/nvim/version.c b/src/nvim/version.c index 4bdc0ba290..9a8a50ea58 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -323,7 +323,7 @@ static int included_patches[] = { 601, 600, 599, - // 598, + 598, 597, // 596 NA 595, @@ -476,7 +476,7 @@ static int included_patches[] = { // 448 NA 447, 446, - // 445, + 445, 444, // 443 NA 442, @@ -525,7 +525,7 @@ static int included_patches[] = { // 399 NA // 398 NA 397, - // 396, + 396, 395, // 394 NA // 393 NA diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua index 0550d22fa6..98b8d2dd45 100644 --- a/test/functional/clipboard/clipboard_provider_spec.lua +++ b/test/functional/clipboard/clipboard_provider_spec.lua @@ -285,6 +285,22 @@ describe('clipboard usage', function() the text]]) end) + it('is updated on global changes', function() + insert([[ + text + match + match + text + ]]) + execute('g/match/d') + eq('match\n', eval('getreg("*")')) + feed('u') + eval('setreg("*", "---")') + execute('g/test/') + feed('<esc>') + eq('---', eval('getreg("*")')) + end) + end) describe('with clipboard=unnamedplus', function() @@ -329,6 +345,21 @@ describe('clipboard usage', function() really unnamed the plus]]) end) + it('is updated on global changes', function() + insert([[ + text + match + match + text + ]]) + execute('g/match/d') + eq('match\n', eval('getreg("+")')) + feed('u') + eval('setreg("+", "---")') + execute('g/test/') + feed('<esc>') + eq('---', eval('getreg("+")')) + end) end) it('supports :put', function() |