Merge #4700 from AdnoC/keep-default-register

This commit is contained in:
Justin M. Keyes 2017-05-31 23:43:40 +02:00 committed by GitHub
commit 133f8bc628
9 changed files with 207 additions and 59 deletions

View File

@ -45,7 +45,7 @@ call map(copy(s:SHADA_ENTRY_NAMES),
let s:SHADA_MAP_ENTRIES = { let s:SHADA_MAP_ENTRIES = {
\'search_pattern': ['sp', 'sh', 'ss', 'sb', 'sm', 'sc', 'sl', 'se', 'so', \'search_pattern': ['sp', 'sh', 'ss', 'sb', 'sm', 'sc', 'sl', 'se', 'so',
\ 'su'], \ 'su'],
\'register': ['n', 'rc', 'rw', 'rt'], \'register': ['n', 'rc', 'rw', 'rt', 'ru'],
\'global_mark': ['n', 'f', 'l', 'c'], \'global_mark': ['n', 'f', 'l', 'c'],
\'local_mark': ['f', 'n', 'l', 'c'], \'local_mark': ['f', 'n', 'l', 'c'],
\'jump': ['f', 'l', 'c'], \'jump': ['f', 'l', 'c'],
@ -139,6 +139,7 @@ let s:SHADA_STANDARD_KEYS = {
\'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE], \'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE],
\'rw': ['block width', 'uint', 0], \'rw': ['block width', 'uint', 0],
\'rc': ['contents', 'binarray', s:SHADA_REQUIRED], \'rc': ['contents', 'binarray', s:SHADA_REQUIRED],
\'ru': ['is_unnamed', 'boolean', g:msgpack#false],
\'n': ['name', 'intchar', char2nr('"')], \'n': ['name', 'intchar', char2nr('"')],
\'l': ['line number', 'uint', 1], \'l': ['line number', 'uint', 1],
\'c': ['column', 'uint', 0], \'c': ['column', 'uint', 0],

View File

@ -6719,6 +6719,8 @@ setreg({regname}, {value} [, {options}])
used as the width of the selection - if it is not specified used as the width of the selection - if it is not specified
then the width of the block is set to the number of characters then the width of the block is set to the number of characters
in the longest line (counting a <Tab> as 1 character). in the longest line (counting a <Tab> as 1 character).
If {options} contains "u" or '"', then the unnamed register is
set to point to register {regname}.
If {options} contains no register settings, then the default If {options} contains no register settings, then the default
is to use character mode unless {value} ends in a <NL> for is to use character mode unless {value} ends in a <NL> for

View File

@ -1281,29 +1281,32 @@ exactly four MessagePack objects:
5 (Register) Map describing one register (|registers|). If key 5 (Register) Map describing one register (|registers|). If key
value is equal to default then it is normally not value is equal to default then it is normally not
present. Keys: present. Keys:
Key Type Def Description ~ Key Type Def Description ~
rt UInteger 0 Register type: rt UInteger 0 Register type:
No Description ~ No Description ~
0 |characterwise-register| 0 |characterwise-register|
1 |linewise-register| 1 |linewise-register|
2 |blockwise-register| 2 |blockwise-register|
rw UInteger 0 Register width. Only valid rw UInteger 0 Register width. Only valid
for |blockwise-register|s. for |blockwise-register|s.
rc Array of binary N/A Register contents. Each rc Array of binary N/A Register contents. Each
entry in the array entry in the array
represents its own line. represents its own line.
NUL characters inside the NUL characters inside the
line should be represented line should be represented
as NL according to as NL according to
|NL-used-for-Nul|. |NL-used-for-Nul|.
n UInteger N/A Register name: character ru Boolean false Unnamed register. Whether
code in range [1, 255]. the unnamed register had
Example: |quote0| register pointed to this register.
has name 48 (ASCII code for n UInteger N/A Register name: character
zero character). code in range [1, 255].
* any none Other keys are allowed Example: |quote0| register
for compatibility reasons, has name 48 (ASCII code for
see |shada-compatibility|. zero character).
* any none Other keys are allowed
for compatibility reasons,
see |shada-compatibility|.
6 (Variable) Array containing two items: variable name (binary) and 6 (Variable) Array containing two items: variable name (binary) and
variable value (any object). Values are converted variable value (any object). Values are converted
using the same code |msgpackparse()| uses when reading, using the same code |msgpackparse()| uses when reading,

View File

@ -5100,7 +5100,8 @@ bool garbage_collect(bool testing)
do { do {
yankreg_T reg; yankreg_T reg;
char name = NUL; char name = NUL;
reg_iter = op_register_iter(reg_iter, &name, &reg); bool is_unnamed = false;
reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
if (name != NUL) { if (name != NUL) {
ABORTING(set_ref_dict)(reg.additional_data, copyID); ABORTING(set_ref_dict)(reg.additional_data, copyID);
} }
@ -14834,6 +14835,7 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
regname = '"'; regname = '"';
} }
bool set_unnamed = false;
if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_UNKNOWN) {
const char *stropt = tv_get_string_chk(&argvars[2]); const char *stropt = tv_get_string_chk(&argvars[2]);
if (stropt == NULL) { if (stropt == NULL) {
@ -14862,6 +14864,10 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
break; break;
} }
case 'u': case '"': { // unnamed register
set_unnamed = true;
break;
}
} }
} }
} }
@ -14914,6 +14920,11 @@ free_lstval:
append, yank_type, block_len); append, yank_type, block_len);
} }
rettv->vval.v_number = 0; rettv->vval.v_number = 0;
if (set_unnamed) {
// Discard the result. We already handle the error case.
if (op_register_set_previous(regname)) { }
}
} }
/* /*

View File

@ -5780,7 +5780,7 @@ static inline bool reg_empty(const yankreg_T *const reg)
/// @return Pointer that needs to be passed to next `op_register_iter` call or /// @return Pointer that needs to be passed to next `op_register_iter` call or
/// NULL if iteration is over. /// NULL if iteration is over.
const void *op_register_iter(const void *const iter, char *const name, const void *op_register_iter(const void *const iter, char *const name,
yankreg_T *const reg) yankreg_T *const reg, bool *is_unnamed)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{ {
*name = NUL; *name = NUL;
@ -5796,6 +5796,7 @@ const void *op_register_iter(const void *const iter, char *const name,
int iter_off = (int)(iter_reg - &(y_regs[0])); int iter_off = (int)(iter_reg - &(y_regs[0]));
*name = (char)get_register_name(iter_off); *name = (char)get_register_name(iter_off);
*reg = *iter_reg; *reg = *iter_reg;
*is_unnamed = (iter_reg == y_previous);
while (++iter_reg - &(y_regs[0]) < NUM_SAVED_REGISTERS) { while (++iter_reg - &(y_regs[0]) < NUM_SAVED_REGISTERS) {
if (!reg_empty(iter_reg)) { if (!reg_empty(iter_reg)) {
return (void *) iter_reg; return (void *) iter_reg;
@ -5820,10 +5821,11 @@ size_t op_register_amount(void)
/// Set register to a given value /// Set register to a given value
/// ///
/// @param[in] name Register name. /// @param[in] name Register name.
/// @param[in] reg Register value. /// @param[in] reg Register value.
/// @param[in] is_unnamed Whether to set the unnamed regiseter to reg
/// ///
/// @return true on success, false on failure. /// @return true on success, false on failure.
bool op_register_set(const char name, const yankreg_T reg) bool op_register_set(const char name, const yankreg_T reg, bool is_unnamed)
{ {
int i = op_reg_index(name); int i = op_reg_index(name);
if (i == -1) { if (i == -1) {
@ -5831,6 +5833,10 @@ bool op_register_set(const char name, const yankreg_T reg)
} }
free_register(&y_regs[i]); free_register(&y_regs[i]);
y_regs[i] = reg; y_regs[i] = reg;
if (is_unnamed) {
y_previous = &y_regs[i];
}
return true; return true;
} }
@ -5847,3 +5853,20 @@ const yankreg_T *op_register_get(const char name)
} }
return &y_regs[i]; return &y_regs[i];
} }
/// Set the previous yank register
///
/// @param[in] name Register name.
///
/// @return true on success, false on failure.
bool op_register_set_previous(const char name)
FUNC_ATTR_WARN_UNUSED_RESULT
{
int i = op_reg_index(name);
if (i == -1) {
return false;
}
y_previous = &y_regs[i];
return true;
}

View File

@ -98,6 +98,7 @@ KHASH_SET_INIT_STR(strset)
#define REG_KEY_TYPE "rt" #define REG_KEY_TYPE "rt"
#define REG_KEY_WIDTH "rw" #define REG_KEY_WIDTH "rw"
#define REG_KEY_CONTENTS "rc" #define REG_KEY_CONTENTS "rc"
#define REG_KEY_UNNAMED "ru"
#define KEY_LNUM "l" #define KEY_LNUM "l"
#define KEY_COL "c" #define KEY_COL "c"
@ -284,6 +285,7 @@ typedef struct {
char name; char name;
MotionType type; MotionType type;
char **contents; char **contents;
bool is_unnamed;
size_t contents_size; size_t contents_size;
size_t width; size_t width;
dict_T *additional_data; dict_T *additional_data;
@ -473,6 +475,7 @@ static const ShadaEntry sd_default_values[] = {
.type = kMTCharWise, .type = kMTCharWise,
.contents = NULL, .contents = NULL,
.contents_size = 0, .contents_size = 0,
.is_unnamed = false,
.width = 0, .width = 0,
.additional_data = NULL), .additional_data = NULL),
DEF_SDE(Variable, global_var, DEF_SDE(Variable, global_var,
@ -1335,7 +1338,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
.y_width = (colnr_T) cur_entry.data.reg.width, .y_width = (colnr_T) cur_entry.data.reg.width,
.timestamp = cur_entry.timestamp, .timestamp = cur_entry.timestamp,
.additional_data = cur_entry.data.reg.additional_data, .additional_data = cur_entry.data.reg.additional_data,
})) { }, cur_entry.data.reg.is_unnamed)) {
shada_free_shada_entry(&cur_entry); shada_free_shada_entry(&cur_entry);
} }
// Do not free shada entry: its allocated memory was saved above. // Do not free shada entry: its allocated memory was saved above.
@ -1780,6 +1783,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
2 // Register contents and name 2 // Register contents and name
+ ONE_IF_NOT_DEFAULT(entry, reg.type) + ONE_IF_NOT_DEFAULT(entry, reg.type)
+ ONE_IF_NOT_DEFAULT(entry, reg.width) + ONE_IF_NOT_DEFAULT(entry, reg.width)
+ ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
// Additional entries, if any: // Additional entries, if any:
+ (size_t) (entry.data.reg.additional_data == NULL + (size_t) (entry.data.reg.additional_data == NULL
? 0 ? 0
@ -1800,6 +1804,14 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
PACK_STATIC_STR(REG_KEY_WIDTH); PACK_STATIC_STR(REG_KEY_WIDTH);
msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width); msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width);
} }
if (!CHECK_DEFAULT(entry, reg.is_unnamed)) {
PACK_STATIC_STR(REG_KEY_UNNAMED);
if (entry.data.reg.is_unnamed) {
msgpack_pack_true(spacker);
} else {
msgpack_pack_false(spacker);
}
}
DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item"); DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item");
break; break;
} }
@ -2318,6 +2330,48 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
} }
} }
/// Initialize registers for writing to the ShaDa file
///
/// @param[in] wms The WriteMergerState used when writing.
/// @param[in] max_reg_lines The maximum number of register lines.
static inline void shada_initialize_registers(WriteMergerState *const wms,
int max_reg_lines)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
const void *reg_iter = NULL;
const bool limit_reg_lines = max_reg_lines >= 0;
do {
yankreg_T reg;
char name = NUL;
bool is_unnamed = false;
reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
if (name == NUL) {
break;
}
if (limit_reg_lines && reg.y_size > (size_t)max_reg_lines) {
continue;
}
wms->registers[op_reg_index(name)] = (PossiblyFreedShadaEntry) {
.can_free_entry = false,
.data = {
.type = kSDItemRegister,
.timestamp = reg.timestamp,
.data = {
.reg = {
.contents = (char **)reg.y_array,
.contents_size = (size_t)reg.y_size,
.type = reg.y_type,
.width = (size_t)(reg.y_type == kMTBlockWise ? reg.y_width : 0),
.additional_data = reg.additional_data,
.name = name,
.is_unnamed = is_unnamed,
}
}
}
};
} while (reg_iter != NULL);
}
/// Write ShaDa file /// Write ShaDa file
/// ///
/// @param[in] sd_writer Structure containing file writer definition. /// @param[in] sd_writer Structure containing file writer definition.
@ -2344,7 +2398,6 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (max_reg_lines < 0) { if (max_reg_lines < 0) {
max_reg_lines = get_shada_parameter('"'); max_reg_lines = get_shada_parameter('"');
} }
const bool limit_reg_lines = max_reg_lines >= 0;
const bool dump_registers = (max_reg_lines != 0); const bool dump_registers = (max_reg_lines != 0);
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset); khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
const size_t max_kbyte = (size_t) max_kbyte_i; const size_t max_kbyte = (size_t) max_kbyte_i;
@ -2587,35 +2640,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
// Initialize registers // Initialize registers
if (dump_registers) { if (dump_registers) {
const void *reg_iter = NULL; shada_initialize_registers(wms, max_reg_lines);
do {
yankreg_T reg;
char name = NUL;
reg_iter = op_register_iter(reg_iter, &name, &reg);
if (name == NUL) {
break;
}
if (limit_reg_lines && reg.y_size > (size_t)max_reg_lines) {
continue;
}
wms->registers[op_reg_index(name)] = (PossiblyFreedShadaEntry) {
.can_free_entry = false,
.data = {
.type = kSDItemRegister,
.timestamp = reg.timestamp,
.data = {
.reg = {
.contents = (char **) reg.y_array,
.contents_size = (size_t) reg.y_size,
.type = reg.y_type,
.width = (size_t) (reg.y_type == kMTBlockWise ? reg.y_width : 0),
.additional_data = reg.additional_data,
.name = name,
}
}
}
};
} while (reg_iter != NULL);
} }
// Initialize buffers // Initialize buffers
@ -3594,6 +3619,7 @@ shada_read_next_item_start:
entry->data.reg.contents[i] = BIN_CONVERTED(arr.ptr[i].via.bin); entry->data.reg.contents[i] = BIN_CONVERTED(arr.ptr[i].via.bin);
} }
} }
BOOLEAN_KEY("register", REG_KEY_UNNAMED, entry->data.reg.is_unnamed)
TYPED_KEY("register", REG_KEY_TYPE, "an unsigned integer", TYPED_KEY("register", REG_KEY_TYPE, "an unsigned integer",
entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8) entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
TYPED_KEY("register", KEY_NAME_CHAR, "an unsigned integer", TYPED_KEY("register", KEY_NAME_CHAR, "an unsigned integer",

View File

@ -516,6 +516,15 @@ describe('eval', function()
eq({'item'}, eval("y")) eq({'item'}, eval("y"))
end) end)
it('sets the unnamed register when the "u" option is passed to setreg', function()
command("call setreg('a','a reg', 'cu')")
eq("a reg", eval('@"'))
command("call setreg('b','b reg', 'cu')")
eq("b reg", eval('@"'))
command("call setreg('c','c reg', 'c')")
eq("b reg", eval('@"'))
end)
it('search and expressions', function() it('search and expressions', function()
command('so test_eval_setup.vim') command('so test_eval_setup.vim')
command([=[call SetReg('/', ['abc/'])]=]) command([=[call SetReg('/', ['abc/'])]=])

View File

@ -179,6 +179,7 @@ describe('In autoload/shada.vim', function()
' + n name \'@\'', ' + n name \'@\'',
' + rc contents ["abc", "def"]', ' + rc contents ["abc", "def"]',
' + rt type CHARACTERWISE', ' + rt type CHARACTERWISE',
' + ru is_unnamed FALSE',
' + rw block width 10', ' + rw block width 10',
' + sb search backward TRUE', ' + sb search backward TRUE',
' + sc smartcase value FALSE', ' + sc smartcase value FALSE',
@ -204,6 +205,7 @@ describe('In autoload/shada.vim', function()
'rt': 0, 'rt': 0,
'rw': 10, 'rw': 10,
'rc': ['abc', 'def'], 'rc': ['abc', 'def'],
'ru': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
'n': 0x40, 'n': 0x40,
'l': 10, 'l': 10,
'c': 0, 'c': 0,
@ -226,6 +228,8 @@ describe('In autoload/shada.vim', function()
.. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)', .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)',
' + rt type 10', ' + rt type 10',
' # Expected boolean', ' # Expected boolean',
' + ru is_unnamed 10',
' # Expected boolean',
' + sc smartcase value NIL', ' + sc smartcase value NIL',
' # Expected boolean', ' # Expected boolean',
' + sm magic value "TRUE"', ' + sm magic value "TRUE"',
@ -240,6 +244,7 @@ describe('In autoload/shada.vim', function()
'sp': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]}, 'sp': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]},
'rt': 10, 'rt': 10,
'rc': '10', 'rc': '10',
'ru': 10,
'n': -0x40, 'n': -0x40,
'l': -10, 'l': -10,
'c': 'abc', 'c': 'abc',
@ -636,6 +641,7 @@ describe('In autoload/shada.vim', function()
' # Required key missing: rc', ' # Required key missing: rc',
' + rw block width 0', ' + rw block width 0',
' + rt type CHARACTERWISE', ' + rt type CHARACTERWISE',
' + ru is_unnamed FALSE',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
}}] ]]):gsub('\n', '')) }}] ]]):gsub('\n', ''))
sd2strings_eq({ sd2strings_eq({
@ -645,6 +651,7 @@ describe('In autoload/shada.vim', function()
' # Required key missing: rc', ' # Required key missing: rc',
' + rw block width 0', ' + rw block width 0',
' + rt type CHARACTERWISE', ' + rt type CHARACTERWISE',
' + ru is_unnamed FALSE',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20, 'n': 0x20,
}}] ]]):gsub('\n', '')) }}] ]]):gsub('\n', ''))
@ -655,9 +662,11 @@ describe('In autoload/shada.vim', function()
' + rc contents ["abc", "def"]', ' + rc contents ["abc", "def"]',
' + rw block width 0', ' + rw block width 0',
' + rt type CHARACTERWISE', ' + rt type CHARACTERWISE',
' + ru is_unnamed FALSE',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20, 'n': 0x20,
'rc': ["abc", "def"], 'rc': ["abc", "def"],
'ru': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
}}] ]]):gsub('\n', '')) }}] ]]):gsub('\n', ''))
sd2strings_eq({ sd2strings_eq({
'Register with timestamp ' .. epoch .. ':', 'Register with timestamp ' .. epoch .. ':',
@ -668,9 +677,11 @@ describe('In autoload/shada.vim', function()
' | - "abcdefghijklmnopqrstuvwxyz"', ' | - "abcdefghijklmnopqrstuvwxyz"',
' + rw block width 0', ' + rw block width 0',
' + rt type CHARACTERWISE', ' + rt type CHARACTERWISE',
' + ru is_unnamed TRUE',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20, 'n': 0x20,
'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
'ru': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
}}] ]]):gsub('\n', '')) }}] ]]):gsub('\n', ''))
sd2strings_eq({ sd2strings_eq({
'Register with timestamp ' .. epoch .. ':', 'Register with timestamp ' .. epoch .. ':',
@ -681,6 +692,7 @@ describe('In autoload/shada.vim', function()
' | - "abcdefghijklmnopqrstuvwxyz"', ' | - "abcdefghijklmnopqrstuvwxyz"',
' + rw block width 0', ' + rw block width 0',
' + rt type CHARACTERWISE', ' + rt type CHARACTERWISE',
' + ru is_unnamed FALSE',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20, 'n': 0x20,
'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
@ -696,6 +708,7 @@ describe('In autoload/shada.vim', function()
' | - "abcdefghijklmnopqrstuvwxyz"', ' | - "abcdefghijklmnopqrstuvwxyz"',
' + rw block width 5', ' + rw block width 5',
' + rt type LINEWISE', ' + rt type LINEWISE',
' + ru is_unnamed FALSE',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20, 'n': 0x20,
'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
@ -712,11 +725,14 @@ describe('In autoload/shada.vim', function()
' # Expected integer', ' # Expected integer',
' + rw block width ""', ' + rw block width ""',
' + rt type BLOCKWISE', ' + rt type BLOCKWISE',
' # Expected boolean',
' + ru is_unnamed ""',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20, 'n': 0x20,
'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
'rw': "", 'rw': "",
'rt': 2, 'rt': 2,
'ru': ""
}}] ]]):gsub('\n', '')) }}] ]]):gsub('\n', ''))
sd2strings_eq({ sd2strings_eq({
'Register with timestamp ' .. epoch .. ':', 'Register with timestamp ' .. epoch .. ':',
@ -729,11 +745,32 @@ describe('In autoload/shada.vim', function()
' # Unexpected enum value: expected one of 0 (CHARACTERWISE), ' ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), '
.. '1 (LINEWISE), 2 (BLOCKWISE)', .. '1 (LINEWISE), 2 (BLOCKWISE)',
' + rt type 10', ' + rt type 10',
' # Expected boolean',
' + ru is_unnamed ["abc", "def"]',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': { }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20, 'n': 0x20,
'rc': 0, 'rc': 0,
'rw': -1, 'rw': -1,
'rt': 10, 'rt': 10,
'ru': ['abc', 'def'],
}}] ]]):gsub('\n', ''))
sd2strings_eq({
'Register with timestamp ' .. epoch .. ':',
' % Key Description Value',
' + n name \' \'',
' + rc contents @',
' | - "abcdefghijklmnopqrstuvwxyz"',
' | - "abcdefghijklmnopqrstuvwxyz"',
' + rw block width 5',
' + rt type LINEWISE',
' # Expected boolean',
' + ru is_unnamed 0',
}, ([[ [{'type': 5, 'timestamp': 0, 'data': {
'n': 0x20,
'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
'rw': 5,
'rt': 1,
'ru': 0,
}}] ]]):gsub('\n', '')) }}] ]]):gsub('\n', ''))
end) end)

View File

@ -148,4 +148,40 @@ describe('ShaDa support code', function()
eq({{'\171«'}, 'v'}, getreg('e')) eq({{'\171«'}, 'v'}, getreg('e'))
end) end)
it('has a blank unnamed register if it wasn\'t set and register 0 is empty',
function()
setreg('1', {'one'}, 'c')
setreg('2', {'two'}, 'c')
setreg('a', {'a'}, 'c')
nvim_command('qall')
reset()
eq({{}, ''}, getreg('0'))
eq({{'one'}, 'v'}, getreg('1'))
eq({{}, ''}, getreg('"'))
eq({{'a'}, 'v'}, getreg('a'))
end)
it('defaults the unnamed register to register 0 if it wasn\'t set',
function()
setreg('0', {'zero'}, 'c')
setreg('1', {'one'}, 'c')
setreg('2', {'two'}, 'c')
nvim_command('qall')
reset()
eq({{'zero'}, 'v'}, getreg('0'))
eq({{'one'}, 'v'}, getreg('1'))
eq({{'zero'}, 'v'}, getreg('"'))
end)
it('remembers which register was the unnamed register when loading',
function()
setreg('0', {'zero'}, 'c')
setreg('1', {'one'}, 'cu')
setreg('2', {'two'}, 'c')
nvim_command('qall')
reset()
eq({{'zero'}, 'v'}, getreg('0'))
eq({{'one'}, 'v'}, getreg('1'))
eq({{'one'}, 'v'}, getreg('"'))
end)
end) end)