aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2017-05-31 23:43:40 +0200
committerGitHub <noreply@github.com>2017-05-31 23:43:40 +0200
commit133f8bc628c20510571a9f6c93b61a14521327d1 (patch)
treea0d8fdef972c4d203e76b914720f78b404beeffe /src
parentc1026ff4b3b6500c06d5a2233214addbb41936cb (diff)
parent2f2eeb19ba7ba6f8b7789d7d10c9e821d4ea3351 (diff)
downloadrneovim-133f8bc628c20510571a9f6c93b61a14521327d1.tar.gz
rneovim-133f8bc628c20510571a9f6c93b61a14521327d1.tar.bz2
rneovim-133f8bc628c20510571a9f6c93b61a14521327d1.zip
Merge #4700 from AdnoC/keep-default-register
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c13
-rw-r--r--src/nvim/ops.c29
-rw-r--r--src/nvim/shada.c88
3 files changed, 95 insertions, 35 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 4e303414a3..7187386ec7 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5100,7 +5100,8 @@ bool garbage_collect(bool testing)
do {
yankreg_T reg;
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) {
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 = '"';
}
+ bool set_unnamed = false;
if (argvars[2].v_type != VAR_UNKNOWN) {
const char *stropt = tv_get_string_chk(&argvars[2]);
if (stropt == NULL) {
@@ -14862,6 +14864,10 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
break;
}
+ case 'u': case '"': { // unnamed register
+ set_unnamed = true;
+ break;
+ }
}
}
}
@@ -14914,6 +14920,11 @@ free_lstval:
append, yank_type, block_len);
}
rettv->vval.v_number = 0;
+
+ if (set_unnamed) {
+ // Discard the result. We already handle the error case.
+ if (op_register_set_previous(regname)) { }
+ }
}
/*
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index c77781b1d1..e374686286 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -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
/// NULL if iteration is over.
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
{
*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]));
*name = (char)get_register_name(iter_off);
*reg = *iter_reg;
+ *is_unnamed = (iter_reg == y_previous);
while (++iter_reg - &(y_regs[0]) < NUM_SAVED_REGISTERS) {
if (!reg_empty(iter_reg)) {
return (void *) iter_reg;
@@ -5820,10 +5821,11 @@ size_t op_register_amount(void)
/// Set register to a given value
///
/// @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.
-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);
if (i == -1) {
@@ -5831,6 +5833,10 @@ bool op_register_set(const char name, const yankreg_T reg)
}
free_register(&y_regs[i]);
y_regs[i] = reg;
+
+ if (is_unnamed) {
+ y_previous = &y_regs[i];
+ }
return true;
}
@@ -5847,3 +5853,20 @@ const yankreg_T *op_register_get(const char name)
}
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;
+}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 87b4617099..4788b1e7d0 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -98,6 +98,7 @@ KHASH_SET_INIT_STR(strset)
#define REG_KEY_TYPE "rt"
#define REG_KEY_WIDTH "rw"
#define REG_KEY_CONTENTS "rc"
+#define REG_KEY_UNNAMED "ru"
#define KEY_LNUM "l"
#define KEY_COL "c"
@@ -284,6 +285,7 @@ typedef struct {
char name;
MotionType type;
char **contents;
+ bool is_unnamed;
size_t contents_size;
size_t width;
dict_T *additional_data;
@@ -473,6 +475,7 @@ static const ShadaEntry sd_default_values[] = {
.type = kMTCharWise,
.contents = NULL,
.contents_size = 0,
+ .is_unnamed = false,
.width = 0,
.additional_data = NULL),
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,
.timestamp = cur_entry.timestamp,
.additional_data = cur_entry.data.reg.additional_data,
- })) {
+ }, cur_entry.data.reg.is_unnamed)) {
shada_free_shada_entry(&cur_entry);
}
// 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
+ ONE_IF_NOT_DEFAULT(entry, reg.type)
+ ONE_IF_NOT_DEFAULT(entry, reg.width)
+ + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
// Additional entries, if any:
+ (size_t) (entry.data.reg.additional_data == NULL
? 0
@@ -1800,6 +1804,14 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
PACK_STATIC_STR(REG_KEY_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");
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
///
/// @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) {
max_reg_lines = get_shada_parameter('"');
}
- const bool limit_reg_lines = max_reg_lines >= 0;
const bool dump_registers = (max_reg_lines != 0);
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
const size_t max_kbyte = (size_t) max_kbyte_i;
@@ -2587,35 +2640,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
// Initialize registers
if (dump_registers) {
- const void *reg_iter = NULL;
- 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);
+ shada_initialize_registers(wms, max_reg_lines);
}
// Initialize buffers
@@ -3594,6 +3619,7 @@ shada_read_next_item_start:
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",
entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
TYPED_KEY("register", KEY_NAME_CHAR, "an unsigned integer",