shada: Set the unnamed register to the previous unnamed register on startup

This commit is contained in:
AdnoC
2016-05-04 14:12:50 -04:00
parent 2dc27a8a78
commit a00b03d03f
4 changed files with 54 additions and 30 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

@@ -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

@@ -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;
@@ -5819,11 +5820,12 @@ 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;
} }

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"
@@ -286,6 +287,7 @@ typedef struct {
char **contents; char **contents;
size_t contents_size; size_t contents_size;
size_t width; size_t width;
bool is_unnamed;
dict_T *additional_data; dict_T *additional_data;
} reg; } reg;
struct global_var { struct global_var {
@@ -1335,7 +1337,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 +1782,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 +1803,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;
} }
@@ -2591,7 +2602,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
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) {
break; break;
} }
@@ -2611,6 +2623,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.width = (size_t) (reg.y_type == kMTBlockWise ? reg.y_width : 0), .width = (size_t) (reg.y_type == kMTBlockWise ? reg.y_width : 0),
.additional_data = reg.additional_data, .additional_data = reg.additional_data,
.name = name, .name = name,
.is_unnamed = is_unnamed,
} }
} }
} }
@@ -3594,6 +3607,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",