mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 11:15:14 -07:00
clipboard: avoid clipboard during :global. #2809
This is equivalent to patches 7.4.396, 7.4.445 and 7.4.598. vim-patch:7.4.396 Problem: When 'clipboard' is "unnamed", :g/pat/d is very slow. (Praful) Solution: Only set the clipboard after the last delete. (Christian Brabandt)1f285eb49a
vim-patch:7.4.445 Problem: Clipboard may be cleared on startup. Solution: Set clip_did_set_selection to -1 during startup. (Christian Brabandt)1a19d37d90
vim-patch:7.4.598 Problem: ":tabdo windo echo 'hi'" causes "* register not to be changed. (Salman Halim) Solution: Change how clip_did_set_selection is used and add clipboard_needs_update and global_change_count. (Christian Brabandt)af6a579263
Co-Author: @bfredl
This commit is contained in:
parent
7ee94d2dd7
commit
acdac914d5
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)')
|
||||
|
Binary file not shown.
@ -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
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user