mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
clipboard: remove start_batch_changes() in redir_write()
start_batch_changes() doesn't avoid invoking the clipboard once-per-line, because the loop is actually in ex_echo(), which calls redir_write() for each message. But we've already entered start_batch_changes() by then, so that was never the problem. redir_write at /home/vagrant/old.neovim/build/../src/nvim/message.c:2523 msg_puts_attr_len at /home/vagrant/old.neovim/build/../src/nvim/message.c:1600 msg_outtrans_len_attr at /home/vagrant/old.neovim/build/../src/nvim/message.c:1221 ex_echo at /home/vagrant/old.neovim/build/../src/nvim/eval.c:19433 do_one_cmd at /home/vagrant/old.neovim/build/../src/nvim/ex_docmd.c:2242 Trying to defer _explicit_ clipboard updates is difficult. :redir @+ | silent echo system('cat foo') | redir END is essentially equivalent to: for l in readfile('foo') let @+ .= l endfor We cannot make judgements about when to ignore a script's bad decisions. start_batch_changes() only works around the case of clipboard=unnamed, i.e. _implicit_ clipboard updates (`:g/foo/d`). Not explicit assignment.
This commit is contained in:
parent
9882e25dc4
commit
cc7e344f83
@ -2519,7 +2519,6 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen)
|
||||
if (redirecting()) {
|
||||
/* If the string doesn't start with CR or NL, go to msg_col */
|
||||
if (*s != '\n' && *s != '\r') {
|
||||
start_batch_changes();
|
||||
while (cur_col < msg_col) {
|
||||
if (capture_ga) {
|
||||
ga_concat_len(capture_ga, " ", 1);
|
||||
@ -2536,7 +2535,6 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen)
|
||||
}
|
||||
cur_col++;
|
||||
}
|
||||
end_batch_changes();
|
||||
}
|
||||
|
||||
size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen;
|
||||
|
@ -5558,7 +5558,7 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
|
||||
msg((char_u *)MSG_NO_CLIP);
|
||||
clipboard_didwarn_unnamed = true;
|
||||
}
|
||||
// ... else, be silent (avoid a flood of messages).
|
||||
// ... else, be silent (don't flood during :while, :redir, etc.).
|
||||
goto end;
|
||||
}
|
||||
|
||||
@ -5567,10 +5567,12 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
|
||||
goto end;
|
||||
} else { // unnamed register: "implicit" clipboard
|
||||
if (writing && clipboard_delay_update) {
|
||||
// For "set" (copy), defer the clipboard call.
|
||||
clipboard_needs_update = true;
|
||||
goto end;
|
||||
} else if (!writing && clipboard_needs_update) {
|
||||
goto end; // use the internal value
|
||||
// For "get" (paste), use the internal value.
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cb_flags & CB_UNNAMEDPLUS) {
|
||||
@ -5772,6 +5774,7 @@ void end_batch_changes(void)
|
||||
}
|
||||
clipboard_delay_update = false;
|
||||
if (clipboard_needs_update) {
|
||||
// unnamed ("implicit" clipboard)
|
||||
set_clipboard(NUL, y_previous);
|
||||
clipboard_needs_update = false;
|
||||
}
|
||||
|
@ -93,17 +93,16 @@ describe('clipboard', function()
|
||||
local screen = Screen.new(72, 8)
|
||||
screen:attach()
|
||||
command("let g:clipboard = 'bogus'")
|
||||
feed_command('redir @+> | :call system("cat CONTRIBUTING.md") | redir END')
|
||||
-- it is made empty
|
||||
feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END')
|
||||
screen:expect([[
|
||||
^ |
|
||||
~ |
|
||||
~ |
|
||||
~ |
|
||||
~ |
|
||||
~ |
|
||||
~ |
|
||||
Error detected while processing function provider#clipboard#Executable: |
|
||||
line 5: |
|
||||
clipboard: invalid g:clipboard |
|
||||
clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
|
||||
Press ENTER or type command to continue^ |
|
||||
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
|
||||
end)
|
||||
end)
|
||||
@ -118,7 +117,23 @@ describe('clipboard', function()
|
||||
feed_command('call getreg("*")') -- force load of provider
|
||||
end)
|
||||
|
||||
it('has independent "* and unnamed registers per default', function()
|
||||
it('`:redir @+>` invokes clipboard once-per-message', function()
|
||||
eq(0, eval("g:clip_called_set"))
|
||||
feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END')
|
||||
-- Assuming CONTRIBUTING.md has >100 lines.
|
||||
assert(eval("g:clip_called_set") > 100)
|
||||
end)
|
||||
|
||||
it('`:redir @">` does not invoke clipboard', function()
|
||||
-- :redir to a non-clipboard register, with `:set clipboard=unnamed`.
|
||||
-- Does _not_ propagate to the clipboard (complies with Vim behavior).
|
||||
command("set clipboard=unnamedplus")
|
||||
eq(0, eval("g:clip_called_set"))
|
||||
feed_command('redir @"> | :silent echo system("cat CONTRIBUTING.md") | redir END')
|
||||
eq(0, eval("g:clip_called_set"))
|
||||
end)
|
||||
|
||||
it('has independent "* and unnamed registers per default', function()
|
||||
insert("some words")
|
||||
feed('^"*dwdw"*P')
|
||||
expect('some ')
|
||||
@ -325,7 +340,7 @@ describe('clipboard', function()
|
||||
|
||||
end)
|
||||
|
||||
describe('with clipboard=unnamedplus', function()
|
||||
describe('clipboard=unnamedplus', function()
|
||||
before_each(function()
|
||||
feed_command('set clipboard=unnamedplus')
|
||||
end)
|
||||
@ -369,6 +384,7 @@ describe('clipboard', function()
|
||||
really unnamed
|
||||
the plus]])
|
||||
end)
|
||||
|
||||
it('is updated on global changes', function()
|
||||
insert([[
|
||||
text
|
||||
|
@ -5,7 +5,13 @@ let s:methods = {}
|
||||
let g:cliplossy = 0
|
||||
let g:cliperror = 0
|
||||
|
||||
" Count how many times the clipboard was invoked.
|
||||
let g:clip_called_get = 0
|
||||
let g:clip_called_set = 0
|
||||
|
||||
function! s:methods.get(reg)
|
||||
let g:clip_called_get += 1
|
||||
|
||||
if g:cliperror
|
||||
return 0
|
||||
end
|
||||
@ -19,6 +25,8 @@ function! s:methods.get(reg)
|
||||
endfunction
|
||||
|
||||
function! s:methods.set(lines, regtype, reg)
|
||||
let g:clip_called_set += 1
|
||||
|
||||
if a:reg == '"'
|
||||
call s:methods.set(a:lines,a:regtype,'+')
|
||||
call s:methods.set(a:lines,a:regtype,'*')
|
||||
|
Loading…
Reference in New Issue
Block a user