mirror of
https://github.com/neovim/neovim
synced 2025-07-21 05:42:46 +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
(cherry picked from commit 7432781e71
)
This commit is contained in:
committed by
github-actions[bot]
parent
b694131c3b
commit
dcd5e4574a
@ -3244,7 +3244,7 @@ static void ins_reg(void)
|
|||||||
|
|
||||||
do_put(regname, NULL, BACKWARD, 1,
|
do_put(regname, NULL, BACKWARD, 1,
|
||||||
(literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND);
|
(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);
|
vim_beep(kOptBoFlagRegister);
|
||||||
need_redraw = true; // remove the '"'
|
need_redraw = true; // remove the '"'
|
||||||
} else if (stop_insert_mode) {
|
} 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).
|
// happens for the GUI).
|
||||||
if ((State & MODE_INSERT)) {
|
if ((State & MODE_INSERT)) {
|
||||||
if (regname == '.') {
|
if (regname == '.') {
|
||||||
insert_reg(regname, true);
|
insert_reg(regname, NULL, true);
|
||||||
} else {
|
} else {
|
||||||
if (regname == 0 && eval_has_provider("clipboard", false)) {
|
if (regname == 0 && eval_has_provider("clipboard", false)) {
|
||||||
regname = '*';
|
regname = '*';
|
||||||
}
|
}
|
||||||
if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) {
|
yankreg_T *reg = NULL;
|
||||||
insert_reg(regname, true);
|
if ((State & REPLACE_FLAG) && !yank_register_mline(regname, ®)) {
|
||||||
|
insert_reg(regname, reg, true);
|
||||||
} else {
|
} else {
|
||||||
do_put(regname, NULL, BACKWARD, 1,
|
do_put(regname, reg, BACKWARD, 1,
|
||||||
(fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND);
|
(fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND);
|
||||||
|
|
||||||
// Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r
|
// 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)) {
|
if (regname == 0 && eval_has_provider("clipboard", false)) {
|
||||||
regname = '*';
|
regname = '*';
|
||||||
}
|
}
|
||||||
if (yank_register_mline(regname)) {
|
yankreg_T *reg = NULL;
|
||||||
|
if (yank_register_mline(regname, ®)) {
|
||||||
if (mouse_past_bottom) {
|
if (mouse_past_bottom) {
|
||||||
dir = FORWARD;
|
dir = FORWARD;
|
||||||
}
|
}
|
||||||
@ -855,7 +857,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
|||||||
if (restart_edit != 0) {
|
if (restart_edit != 0) {
|
||||||
where_paste_started = curwin->w_cursor;
|
where_paste_started = curwin->w_cursor;
|
||||||
}
|
}
|
||||||
do_put(regname, NULL, dir, count,
|
do_put(regname, reg, dir, count,
|
||||||
(fixindent ? PUT_FIXINDENT : 0)| PUT_CURSEND);
|
(fixindent ? PUT_FIXINDENT : 0)| PUT_CURSEND);
|
||||||
} else if (((mod_mask & MOD_MASK_CTRL) || (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
|
} else if (((mod_mask & MOD_MASK_CTRL) || (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
|
||||||
&& bt_quickfix(curbuf)) {
|
&& bt_quickfix(curbuf)) {
|
||||||
|
@ -966,16 +966,23 @@ yankreg_T *copy_register(int name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the current yank register has kMTLineWise register type
|
/// 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)) {
|
if (regname != 0 && !valid_yank_reg(regname, false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (regname == '_') { // black hole is always empty
|
if (regname == '_') { // black hole is always empty
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
|
*reg = get_yank_register(regname, YREG_PASTE);
|
||||||
return reg->y_type == kMTLineWise;
|
return (*reg)->y_type == kMTLineWise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start or stop recording into a yank register.
|
/// 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
|
/// @param literally_arg insert literally, not as if typed
|
||||||
///
|
///
|
||||||
/// @return FAIL for failure, OK otherwise
|
/// @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;
|
int retval = OK;
|
||||||
bool allocated;
|
bool allocated;
|
||||||
@ -1353,7 +1360,9 @@ int insert_reg(int regname, bool literally_arg)
|
|||||||
xfree(arg);
|
xfree(arg);
|
||||||
}
|
}
|
||||||
} else { // Name or number register.
|
} 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) {
|
if (reg->y_array == NULL) {
|
||||||
retval = FAIL;
|
retval = FAIL;
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user