mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #2411 from bfredl/yankregs
Cleanup implementation of registers and fix missing clipboard support in `:redir`
This commit is contained in:
commit
a88e2f4fd4
@ -6752,7 +6752,7 @@ static void ins_reg(void)
|
|||||||
|
|
||||||
regname = get_expr_register();
|
regname = get_expr_register();
|
||||||
}
|
}
|
||||||
if (regname == NUL || !valid_yank_reg(regname, FALSE)) {
|
if (regname == NUL || !valid_yank_reg(regname, false)) {
|
||||||
vim_beep();
|
vim_beep();
|
||||||
need_redraw = TRUE; /* remove the '"' */
|
need_redraw = TRUE; /* remove the '"' */
|
||||||
} else {
|
} else {
|
||||||
@ -6762,7 +6762,7 @@ static void ins_reg(void)
|
|||||||
AppendCharToRedobuff(literally);
|
AppendCharToRedobuff(literally);
|
||||||
AppendCharToRedobuff(regname);
|
AppendCharToRedobuff(regname);
|
||||||
|
|
||||||
do_put(regname, BACKWARD, 1L,
|
do_put(regname, NULL, BACKWARD, 1L,
|
||||||
(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, literally) == FAIL) {
|
||||||
vim_beep();
|
vim_beep();
|
||||||
|
@ -13629,13 +13629,12 @@ static void f_setreg(typval_T *argvars, typval_T *rettv)
|
|||||||
int regname;
|
int regname;
|
||||||
char_u *strregname;
|
char_u *strregname;
|
||||||
char_u *stropt;
|
char_u *stropt;
|
||||||
int append;
|
bool append = false;
|
||||||
char_u yank_type;
|
char_u yank_type;
|
||||||
long block_len;
|
long block_len;
|
||||||
|
|
||||||
block_len = -1;
|
block_len = -1;
|
||||||
yank_type = MAUTO;
|
yank_type = MAUTO;
|
||||||
append = FALSE;
|
|
||||||
|
|
||||||
strregname = get_tv_string_chk(argvars);
|
strregname = get_tv_string_chk(argvars);
|
||||||
rettv->vval.v_number = 1; /* FAIL is default */
|
rettv->vval.v_number = 1; /* FAIL is default */
|
||||||
@ -13653,7 +13652,7 @@ static void f_setreg(typval_T *argvars, typval_T *rettv)
|
|||||||
for (; *stropt != NUL; ++stropt)
|
for (; *stropt != NUL; ++stropt)
|
||||||
switch (*stropt) {
|
switch (*stropt) {
|
||||||
case 'a': case 'A': /* append */
|
case 'a': case 'A': /* append */
|
||||||
append = TRUE;
|
append = true;
|
||||||
break;
|
break;
|
||||||
case 'v': case 'c': /* character-wise selection */
|
case 'v': case 'c': /* character-wise selection */
|
||||||
yank_type = MCHAR;
|
yank_type = MCHAR;
|
||||||
|
@ -6487,7 +6487,7 @@ static void ex_operators(exarg_T *eap)
|
|||||||
|
|
||||||
case CMD_yank:
|
case CMD_yank:
|
||||||
oa.op_type = OP_YANK;
|
oa.op_type = OP_YANK;
|
||||||
(void)op_yank(&oa, FALSE, TRUE);
|
(void)op_yank(&oa, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* CMD_rshift or CMD_lshift */
|
default: /* CMD_rshift or CMD_lshift */
|
||||||
@ -6515,7 +6515,7 @@ static void ex_put(exarg_T *eap)
|
|||||||
eap->forceit = TRUE;
|
eap->forceit = TRUE;
|
||||||
}
|
}
|
||||||
curwin->w_cursor.lnum = eap->line2;
|
curwin->w_cursor.lnum = eap->line2;
|
||||||
do_put(eap->regname, eap->forceit ? BACKWARD : FORWARD, 1L,
|
do_put(eap->regname, NULL, eap->forceit ? BACKWARD : FORWARD, 1L,
|
||||||
PUT_LINE|PUT_CURSLINE);
|
PUT_LINE|PUT_CURSLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6738,8 +6738,7 @@ static void ex_redir(exarg_T *eap)
|
|||||||
/* redirect to a register a-z (resp. A-Z for appending) */
|
/* redirect to a register a-z (resp. A-Z for appending) */
|
||||||
close_redir();
|
close_redir();
|
||||||
++arg;
|
++arg;
|
||||||
if (ASCII_ISALPHA(*arg)
|
if (valid_yank_reg(*arg, true) && *arg != '_') {
|
||||||
|| *arg == '"') {
|
|
||||||
redir_reg = *arg++;
|
redir_reg = *arg++;
|
||||||
if (*arg == '>' && arg[1] == '>') /* append */
|
if (*arg == '>' && arg[1] == '>') /* append */
|
||||||
arg += 2;
|
arg += 2;
|
||||||
|
@ -2318,7 +2318,7 @@ cmdline_paste (
|
|||||||
/* check for valid regname; also accept special characters for CTRL-R in
|
/* check for valid regname; also accept special characters for CTRL-R in
|
||||||
* the command line */
|
* the command line */
|
||||||
if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W
|
if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W
|
||||||
&& regname != Ctrl_A && !valid_yank_reg(regname, FALSE))
|
&& regname != Ctrl_A && !valid_yank_reg(regname, false))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
/* A register containing CTRL-R can cause an endless loop. Allow using
|
/* A register containing CTRL-R can cause an endless loop. Allow using
|
||||||
|
@ -1541,7 +1541,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
|||||||
CancelRedo();
|
CancelRedo();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
(void)op_yank(oap, false, !gui_yank);
|
(void)op_yank(oap, !gui_yank);
|
||||||
check_cursor_col();
|
check_cursor_col();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1995,7 +1995,7 @@ do_mouse (
|
|||||||
if ((State & REPLACE_FLAG) && !yank_register_mline(regname))
|
if ((State & REPLACE_FLAG) && !yank_register_mline(regname))
|
||||||
insert_reg(regname, true);
|
insert_reg(regname, true);
|
||||||
else {
|
else {
|
||||||
do_put(regname, BACKWARD, 1L, fixindent | PUT_CURSEND);
|
do_put(regname, NULL, BACKWARD, 1L, fixindent | 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 */
|
||||||
AppendCharToRedobuff(Ctrl_R);
|
AppendCharToRedobuff(Ctrl_R);
|
||||||
@ -2280,7 +2280,7 @@ do_mouse (
|
|||||||
*/
|
*/
|
||||||
if (restart_edit != 0)
|
if (restart_edit != 0)
|
||||||
where_paste_started = curwin->w_cursor;
|
where_paste_started = curwin->w_cursor;
|
||||||
do_put(regname, dir, count, fixindent | PUT_CURSEND);
|
do_put(regname, NULL, dir, count, fixindent | PUT_CURSEND);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Ctrl-Mouse click or double click in a quickfix window jumps to the
|
* Ctrl-Mouse click or double click in a quickfix window jumps to the
|
||||||
@ -5085,7 +5085,7 @@ static void nv_brackets(cmdarg_T *cap)
|
|||||||
curwin->w_cursor = (dir == BACKWARD ? start : end);
|
curwin->w_cursor = (dir == BACKWARD ? start : end);
|
||||||
}
|
}
|
||||||
prep_redo_cmd(cap);
|
prep_redo_cmd(cap);
|
||||||
do_put(regname, dir, cap->count1, PUT_FIXINDENT);
|
do_put(regname, NULL, dir, cap->count1, PUT_FIXINDENT);
|
||||||
if (was_visual) {
|
if (was_visual) {
|
||||||
VIsual = start;
|
VIsual = start;
|
||||||
curwin->w_cursor = end;
|
curwin->w_cursor = end;
|
||||||
@ -7221,7 +7221,7 @@ static void nv_join(cmdarg_T *cap)
|
|||||||
static void nv_put(cmdarg_T *cap)
|
static void nv_put(cmdarg_T *cap)
|
||||||
{
|
{
|
||||||
int regname = 0;
|
int regname = 0;
|
||||||
void *reg1 = NULL, *reg2 = NULL;
|
yankreg_T *savereg = NULL;
|
||||||
bool empty = false;
|
bool empty = false;
|
||||||
bool was_visual = false;
|
bool was_visual = false;
|
||||||
int dir;
|
int dir;
|
||||||
@ -7252,11 +7252,9 @@ static void nv_put(cmdarg_T *cap)
|
|||||||
was_visual = true;
|
was_visual = true;
|
||||||
regname = cap->oap->regname;
|
regname = cap->oap->regname;
|
||||||
if (regname == 0 || regname == '"'
|
if (regname == 0 || regname == '"'
|
||||||
|| VIM_ISDIGIT(regname) || regname == '-'
|
|| VIM_ISDIGIT(regname) || regname == '-') {
|
||||||
) {
|
// The delete might overwrite the register we want to put, save it first
|
||||||
/* The delete is going to overwrite the register we want to
|
savereg = copy_register(regname);
|
||||||
* put, save it first. */
|
|
||||||
reg1 = get_register(regname, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now delete the selected text. */
|
/* Now delete the selected text. */
|
||||||
@ -7270,13 +7268,6 @@ static void nv_put(cmdarg_T *cap)
|
|||||||
/* delete PUT_LINE_BACKWARD; */
|
/* delete PUT_LINE_BACKWARD; */
|
||||||
cap->oap->regname = regname;
|
cap->oap->regname = regname;
|
||||||
|
|
||||||
if (reg1 != NULL) {
|
|
||||||
/* Delete probably changed the register we want to put, save
|
|
||||||
* it first. Then put back what was there before the delete. */
|
|
||||||
reg2 = get_register(regname, false);
|
|
||||||
put_register(regname, reg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* When deleted a linewise Visual area, put the register as
|
/* When deleted a linewise Visual area, put the register as
|
||||||
* lines to avoid it joined with the next line. When deletion was
|
* lines to avoid it joined with the next line. When deletion was
|
||||||
* characterwise, split a line when putting lines. */
|
* characterwise, split a line when putting lines. */
|
||||||
@ -7297,11 +7288,13 @@ static void nv_put(cmdarg_T *cap)
|
|||||||
/* May have been reset in do_put(). */
|
/* May have been reset in do_put(). */
|
||||||
VIsual_active = true;
|
VIsual_active = true;
|
||||||
}
|
}
|
||||||
do_put(cap->oap->regname, dir, cap->count1, flags);
|
do_put(cap->oap->regname, savereg, dir, cap->count1, flags);
|
||||||
|
|
||||||
/* If a register was saved, put it back now. */
|
// If a register was saved, free it
|
||||||
if (reg2 != NULL)
|
if (savereg != NULL) {
|
||||||
put_register(regname, reg2);
|
free_register(savereg);
|
||||||
|
xfree(savereg);
|
||||||
|
}
|
||||||
|
|
||||||
/* What to reselect with "gv"? Selecting the just put text seems to
|
/* What to reselect with "gv"? Selecting the just put text seems to
|
||||||
* be the most useful, since the original text was removed. */
|
* be the most useful, since the original text was removed. */
|
||||||
|
559
src/nvim/ops.c
559
src/nvim/ops.c
File diff suppressed because it is too large
Load Diff
@ -47,6 +47,14 @@ typedef int (*Indenter)(void);
|
|||||||
#define OP_FORMAT2 26 /* "gw" format operator, keeps cursor pos */
|
#define OP_FORMAT2 26 /* "gw" format operator, keeps cursor pos */
|
||||||
#define OP_FUNCTION 27 /* "g@" call 'operatorfunc' */
|
#define OP_FUNCTION 27 /* "g@" call 'operatorfunc' */
|
||||||
|
|
||||||
|
/// Contents of a yank (read-write) register
|
||||||
|
typedef struct yankreg {
|
||||||
|
char_u **y_array; ///< pointer to array of line pointers
|
||||||
|
linenr_T y_size; ///< number of lines in y_array
|
||||||
|
char_u y_type; ///< MLINE, MCHAR or MBLOCK
|
||||||
|
colnr_T y_width; ///< only set if y_type == MBLOCK
|
||||||
|
} yankreg_T;
|
||||||
|
|
||||||
/// Flags for get_reg_contents().
|
/// Flags for get_reg_contents().
|
||||||
enum GRegFlags {
|
enum GRegFlags {
|
||||||
kGRegNoExpr = 1, ///< Do not allow expression register.
|
kGRegNoExpr = 1, ///< Do not allow expression register.
|
||||||
|
@ -73,6 +73,12 @@ local function basic_register_test(noblock)
|
|||||||
stuf, stuff and some more
|
stuf, stuff and some more
|
||||||
me tsome textsome some text, stuff and some more]])
|
me tsome textsome some text, stuff and some more]])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- pasting in visual does unnamed delete of visual selection
|
||||||
|
feed('ggdG')
|
||||||
|
insert("one and two and three")
|
||||||
|
feed('"ayiwbbviw"ap^viwp$viw"-p')
|
||||||
|
expect("two and three and one")
|
||||||
end
|
end
|
||||||
|
|
||||||
describe('the unnamed register', function()
|
describe('the unnamed register', function()
|
||||||
@ -241,6 +247,14 @@ describe('clipboard usage', function()
|
|||||||
eq('\02210', eval('getregtype()'))
|
eq('\02210', eval('getregtype()'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('yanks visual selection when pasting', function()
|
||||||
|
insert("indeed visual")
|
||||||
|
execute("let g:test_clip['*'] = [['clipboard'], 'c']")
|
||||||
|
feed("viwp")
|
||||||
|
eq({{'visual'}, 'v'}, eval("g:test_clip['*']"))
|
||||||
|
expect("indeed clipboard")
|
||||||
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('supports :put', function()
|
it('supports :put', function()
|
||||||
@ -291,4 +305,28 @@ describe('clipboard usage', function()
|
|||||||
feed(':<c-r>*<cr>')
|
feed(':<c-r>*<cr>')
|
||||||
expect('t/u/t/')
|
expect('t/u/t/')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('supports :redir @*>', function()
|
||||||
|
execute("let g:test_clip['*'] = ['stuff']")
|
||||||
|
execute('redir @*>')
|
||||||
|
-- it is made empty
|
||||||
|
eq({{''}, 'v'}, eval("g:test_clip['*']"))
|
||||||
|
execute('let g:test = doesnotexist')
|
||||||
|
feed('<cr>')
|
||||||
|
eq({{
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'E121: Undefined variable: doesnotexist',
|
||||||
|
'E15: Invalid expression: doesnotexist',
|
||||||
|
}, 'v'}, eval("g:test_clip['*']"))
|
||||||
|
execute(':echo "Howdy!"')
|
||||||
|
eq({{
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'E121: Undefined variable: doesnotexist',
|
||||||
|
'E15: Invalid expression: doesnotexist',
|
||||||
|
'',
|
||||||
|
'Howdy!',
|
||||||
|
}, 'v'}, eval("g:test_clip['*']"))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user