mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
fix(mouse): do not fetch clipboard twice when pasting with middle button #33494
Problem: When doing paste operation mouse code tries to figure out it it is dealing with a multi-line register by calling yank_register_mline(), which fetches register data and checks its type. Later the code calls either do_put() or insert_reg() which fetch register data again. This is unnoticeable when working with internal neovim registers, but starts hurting when dealing with clipboards, especially remote one (forwarded X or socket tunnel or similar). Solution: Change yank_register_mline() to also return pointer to the register structure prepared for pasting, and insert_reg() to accept such register pointer and use it if it is supplied. do_put() already has support for accepting a register structure to be used for pasting. Fixes #33493
This commit is contained in:
@ -3250,7 +3250,7 @@ static void ins_reg(void)
|
||||
|
||||
do_put(regname, NULL, BACKWARD, 1,
|
||||
(literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND);
|
||||
} else if (insert_reg(regname, literally) == FAIL) {
|
||||
} else if (insert_reg(regname, NULL, literally) == FAIL) {
|
||||
vim_beep(kOptBoFlagRegister);
|
||||
need_redraw = true; // remove the '"'
|
||||
} else if (stop_insert_mode) {
|
||||
|
@ -503,15 +503,16 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
||||
// happens for the GUI).
|
||||
if ((State & MODE_INSERT)) {
|
||||
if (regname == '.') {
|
||||
insert_reg(regname, true);
|
||||
insert_reg(regname, NULL, true);
|
||||
} else {
|
||||
if (regname == 0 && eval_has_provider("clipboard", false)) {
|
||||
regname = '*';
|
||||
}
|
||||
if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) {
|
||||
insert_reg(regname, true);
|
||||
yankreg_T *reg = NULL;
|
||||
if ((State & REPLACE_FLAG) && !yank_register_mline(regname, ®)) {
|
||||
insert_reg(regname, reg, true);
|
||||
} else {
|
||||
do_put(regname, NULL, BACKWARD, 1,
|
||||
do_put(regname, reg, BACKWARD, 1,
|
||||
(fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND);
|
||||
|
||||
// Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r
|
||||
@ -833,7 +834,8 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
||||
if (regname == 0 && eval_has_provider("clipboard", false)) {
|
||||
regname = '*';
|
||||
}
|
||||
if (yank_register_mline(regname)) {
|
||||
yankreg_T *reg = NULL;
|
||||
if (yank_register_mline(regname, ®)) {
|
||||
if (mouse_past_bottom) {
|
||||
dir = FORWARD;
|
||||
}
|
||||
@ -855,7 +857,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
||||
if (restart_edit != 0) {
|
||||
where_paste_started = curwin->w_cursor;
|
||||
}
|
||||
do_put(regname, NULL, dir, count,
|
||||
do_put(regname, reg, dir, count,
|
||||
(fixindent ? PUT_FIXINDENT : 0)| PUT_CURSEND);
|
||||
} else if (((mod_mask & MOD_MASK_CTRL) || (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
|
||||
&& bt_quickfix(curbuf)) {
|
||||
|
@ -966,16 +966,23 @@ yankreg_T *copy_register(int name)
|
||||
}
|
||||
|
||||
/// Check if the current yank register has kMTLineWise register type
|
||||
bool yank_register_mline(int regname)
|
||||
/// For valid, non-blackhole registers also provides pointer to the register
|
||||
/// structure prepared for pasting.
|
||||
///
|
||||
/// @param regname The name of the register used or 0 for the unnamed register
|
||||
/// @param reg Pointer to store yankreg_T* for the requested register. Will be
|
||||
/// set to NULL for invalid or blackhole registers.
|
||||
bool yank_register_mline(int regname, yankreg_T **reg)
|
||||
{
|
||||
*reg = NULL;
|
||||
if (regname != 0 && !valid_yank_reg(regname, false)) {
|
||||
return false;
|
||||
}
|
||||
if (regname == '_') { // black hole is always empty
|
||||
return false;
|
||||
}
|
||||
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
|
||||
return reg->y_type == kMTLineWise;
|
||||
*reg = get_yank_register(regname, YREG_PASTE);
|
||||
return (*reg)->y_type == kMTLineWise;
|
||||
}
|
||||
|
||||
/// Start or stop recording into a yank register.
|
||||
@ -1322,7 +1329,7 @@ static int put_in_typebuf(char *s, bool esc, bool colon, int silent)
|
||||
/// @param literally_arg insert literally, not as if typed
|
||||
///
|
||||
/// @return FAIL for failure, OK otherwise
|
||||
int insert_reg(int regname, bool literally_arg)
|
||||
int insert_reg(int regname, yankreg_T *reg, bool literally_arg)
|
||||
{
|
||||
int retval = OK;
|
||||
bool allocated;
|
||||
@ -1353,7 +1360,9 @@ int insert_reg(int regname, bool literally_arg)
|
||||
xfree(arg);
|
||||
}
|
||||
} else { // Name or number register.
|
||||
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
|
||||
if (reg == NULL) {
|
||||
reg = get_yank_register(regname, YREG_PASTE);
|
||||
}
|
||||
if (reg->y_array == NULL) {
|
||||
retval = FAIL;
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user