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

@@ -1296,6 +1296,9 @@ exactly four MessagePack objects:
line should be represented line should be represented
as NL according to as NL according to
|NL-used-for-Nul|. |NL-used-for-Nul|.
ru Boolean false Unnamed register. Whether
the unnamed register had
pointed to this register.
n UInteger N/A Register name: character n UInteger N/A Register name: character
code in range [1, 255]. code in range [1, 255].
Example: |quote0| register Example: |quote0| register

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;
@@ -5821,9 +5822,10 @@ size_t op_register_amount(void)
/// ///
/// @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",