Merge pull request #2381 from bfredl/unnamed

fix update v:register and the " register when clipboard=unnamed
This commit is contained in:
Björn Linse 2015-04-11 12:57:38 +02:00
commit 5bd85fd954
3 changed files with 58 additions and 22 deletions

View File

@ -914,7 +914,7 @@ getcount:
&& !oap->op_type && !oap->op_type
&& (idx < 0 || !(nv_cmds[idx].cmd_flags & NV_KEEPREG))) { && (idx < 0 || !(nv_cmds[idx].cmd_flags & NV_KEEPREG))) {
clearop(oap); clearop(oap);
set_reg_var(0); set_reg_var(get_default_register_name());
} }
/* Get the length of mapped chars again after typing a count, second /* Get the length of mapped chars again after typing a count, second

View File

@ -79,7 +79,7 @@ static struct yankreg {
} y_regs[NUM_REGISTERS]; } y_regs[NUM_REGISTERS];
static struct yankreg *y_current; /* ptr to current yankreg */ static struct yankreg *y_current; /* ptr to current yankreg */
static int y_append; /* TRUE when appending */ static bool y_append; /* true when appending */
static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */ static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */
static bool clipboard_didwarn_unnamed = false; static bool clipboard_didwarn_unnamed = false;
@ -773,36 +773,35 @@ typedef enum {
/// Obtain the location that would be read when pasting `regname`. /// Obtain the location that would be read when pasting `regname`.
void get_yank_register(int regname, int mode) void get_yank_register(int regname, int mode)
{ {
int i; y_append = false;
y_append = FALSE; if (mode == YREG_PASTE && get_clipboard(regname, &y_current, false)) {
int unnamedclip = cb_flags & CB_UNNAMEDMASK; // y_current is set to clipboard contents.
if ((regname == 0 || regname == '"') && !unnamedclip && mode != YREG_YANK && y_previous != NULL) { return;
} else if (mode != YREG_YANK && (regname == 0 || regname == '"') && y_previous != NULL) {
y_current = y_previous; y_current = y_previous;
return; return;
} }
i = regname;
if (VIM_ISDIGIT(i)) int i = 0; // when not 0-9, a-z, A-Z or '-'/'+'/'*': use register 0
i -= '0'; if (VIM_ISDIGIT(regname))
else if (ASCII_ISLOWER(i)) i = regname - '0';
i = CharOrdLow(i) + 10; else if (ASCII_ISLOWER(regname))
else if (ASCII_ISUPPER(i)) { i = CharOrdLow(regname) + 10;
i = CharOrdUp(i) + 10; else if (ASCII_ISUPPER(regname)) {
y_append = TRUE; i = CharOrdUp(regname) + 10;
y_append = true;
} else if (regname == '-') } else if (regname == '-')
i = DELETION_REGISTER; i = DELETION_REGISTER;
else if (regname == '*') else if (regname == '*')
i = STAR_REGISTER; i = STAR_REGISTER;
else if (regname == '+') else if (regname == '+')
i = PLUS_REGISTER; i = PLUS_REGISTER;
else /* not 0-9, a-z, A-Z or '-': use register 0 */
i = 0;
y_current = &(y_regs[i]); y_current = &(y_regs[i]);
if (mode == YREG_YANK) { if (mode == YREG_YANK) {
// remember the written register for unnamed paste // remember the written register for unnamed paste
y_previous = y_current; y_previous = y_current;
} else if (mode == YREG_PASTE) {
get_clipboard(regname, &y_current, false);
} }
} }
@ -5310,7 +5309,28 @@ static void free_register(struct yankreg *reg)
y_current = curr; y_current = curr;
} }
// return target register /// Check if the default register (used in an unnamed paste) should be a
/// clipboard register. This happens when `clipboard=unnamed[plus]` is set
/// and a provider is available.
///
/// @returns the name of of a clipboard register that should be used, or `NUL` if none.
int get_default_register_name(void)
{
int name = NUL;
adjust_clipboard_name(&name, true, false);
return name;
}
/// Determine if register `*name` should be used as a clipboard.
/// In an unnammed operation, `*name` is `NUL` and will be adjusted to `'*'/'+'` if
/// `clipboard=unnamed[plus]` is set.
///
/// @param name The name of register, or `NUL` if unnamed.
/// @param quiet Suppress error messages
/// @param writing if we're setting the contents of the clipboard
///
/// @returns the yankreg that should be used, or `NULL`
/// if the register isn't a clipboard or provider isn't available.
static struct yankreg* adjust_clipboard_name(int *name, bool quiet, bool writing) { static struct yankreg* adjust_clipboard_name(int *name, bool quiet, bool writing) {
if (*name == '*' || *name == '+') { if (*name == '*' || *name == '+') {
if(!eval_has_provider("clipboard")) { if(!eval_has_provider("clipboard")) {
@ -5345,11 +5365,11 @@ static struct yankreg* adjust_clipboard_name(int *name, bool quiet, bool writing
return NULL; return NULL;
} }
static void get_clipboard(int name, struct yankreg** target, bool quiet) static bool get_clipboard(int name, struct yankreg** target, bool quiet)
{ {
struct yankreg* reg = adjust_clipboard_name(&name, quiet, false); struct yankreg* reg = adjust_clipboard_name(&name, quiet, false);
if (reg == NULL) { if (reg == NULL) {
return; return false;
} }
free_register(reg); free_register(reg);
@ -5434,7 +5454,7 @@ static void get_clipboard(int name, struct yankreg** target, bool quiet)
} }
*target = reg; *target = reg;
return; return true;
err: err:
if (reg->y_array) { if (reg->y_array) {
@ -5446,6 +5466,8 @@ err:
reg->y_array = NULL; reg->y_array = NULL;
reg->y_size = 0; reg->y_size = 0;
EMSG("clipboard: provider returned invalid data"); EMSG("clipboard: provider returned invalid data");
*target = reg;
return false;
} }
static void set_clipboard(int name) static void set_clipboard(int name)

View File

@ -55,6 +55,12 @@ local function basic_register_test(noblock)
, stuff and some more , stuff and some more
some textsome some text, stuff and some more]]) some textsome some text, stuff and some more]])
-- deleting a line does update ""
feed('ggdd""P')
expect([[
, stuff and some more
some textsome some text, stuff and some more]])
feed('ggw<c-v>jwyggP') feed('ggw<c-v>jwyggP')
if noblock then if noblock then
expect([[ expect([[
@ -72,6 +78,7 @@ end
describe('the unnamed register', function() describe('the unnamed register', function()
before_each(clear) before_each(clear)
it('works without provider', function() it('works without provider', function()
eq('"', eval('v:register'))
basic_register_test() basic_register_test()
end) end)
end) end)
@ -227,6 +234,13 @@ describe('clipboard usage', function()
a line]]) a line]])
end) end)
it('supports v:register and getreg() without parameters', function()
eq('*', eval('v:register'))
execute("let g:test_clip['*'] = [['some block',''], 'b']")
eq('some block', eval('getreg()'))
eq('\02210', eval('getregtype()'))
end)
end) end)
it('supports :put', function() it('supports :put', function()