aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r--src/nvim/ops.c290
1 files changed, 159 insertions, 131 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 4b8382c971..7dd3f665ba 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -12,6 +12,7 @@
#include <uv.h>
#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii_defs.h"
#include "nvim/assert_defs.h"
#include "nvim/autocmd.h"
@@ -273,7 +274,7 @@ void op_shift(oparg_T *oap, bool curs_top, int amount)
vim_snprintf(IObuff, IOSIZE,
NGETTEXT(msg_line_single, msg_line_plural, oap->line_count),
(int64_t)oap->line_count, op, amount);
- msg_attr_keep(IObuff, 0, true, false);
+ msg_hl_keep(IObuff, 0, true, false);
}
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
@@ -871,18 +872,22 @@ static void typval_to_yankreg(yankreg_T* yankreg, typval_T* val)
if (tv_dict_get_tv(dict, "lines", &tv) == OK) {
if (tv.v_type == VAR_STRING) {
- yankreg->y_array = (char**) xcalloc(sizeof(char*), 1);
- yankreg->y_array[0] = strdup(tv.vval.v_string);
+ yankreg->y_array = (String*) xcalloc(1, sizeof(String));
+ yankreg->y_array[0].data = strdup(tv.vval.v_string);
+ yankreg->y_array[0].size = strlen(tv.vval.v_string);
} else if (tv.v_type == VAR_LIST) {
yankreg->y_array =
- (char**) xcalloc(sizeof(char*), (size_t) tv_list_len(tv.vval.v_list));
+ (String*) xcalloc((size_t) tv_list_len(tv.vval.v_list), sizeof(String));
i = 0;
TV_LIST_ITER_CONST(tv.vval.v_list, li, {
if (li->li_tv.v_type == VAR_STRING) {
- yankreg->y_array[i] = strdup(tv_get_string(&li->li_tv));
+ char* tmp = strdup(tv_get_string(&li->li_tv));
+ yankreg->y_array[i].data = tmp;
+ yankreg->y_array[i].size = strlen(tmp);
} else {
- yankreg->y_array[i] = NULL;
+ yankreg->y_array[i].data = NULL;
+ yankreg->y_array[i].size = 0;
}
++ i;
});
@@ -903,11 +908,13 @@ static void typval_to_yankreg(yankreg_T* yankreg, typval_T* val)
case VAR_LIST:
yankreg->y_type = kMTLineWise;
sz = (size_t) tv_list_len(val->vval.v_list);
- yankreg->y_array = (char**) xcalloc(sizeof(char*), sz);
+ yankreg->y_array = (String*) xcalloc(sz, sizeof(String));
yankreg->y_size = sz;
i = 0;
TV_LIST_ITER_CONST(val->vval.v_list, li, {
- yankreg->y_array[i] = strdup(tv_get_string(&li->li_tv));
+ char* tmp = strdup(tv_get_string(&li->li_tv));
+ yankreg->y_array[i].data = tmp;
+ yankreg->y_array[i].size = strlen(tmp);
i ++;
});
break;
@@ -917,8 +924,10 @@ static void typval_to_yankreg(yankreg_T* yankreg, typval_T* val)
yankreg->y_size = 1;
if (val->vval.v_string) {
- yankreg->y_array = (char**) xcalloc(sizeof(char*), 1);
- yankreg->y_array[0] = strdup(tv_get_string(val));
+ yankreg->y_array = (String*) xcalloc(1, sizeof(String));
+ char* tmp = strdup(tv_get_string(val));
+ yankreg->y_array[0].data = tmp;
+ yankreg->y_array[0].size = strlen(tmp);
} else {
yankreg->y_array = NULL;
}
@@ -1024,9 +1033,9 @@ yankreg_T *copy_register(int name)
if (copy->y_size == 0) {
copy->y_array = NULL;
} else {
- copy->y_array = (char**) xcalloc(copy->y_size, sizeof(char *));
+ copy->y_array = xcalloc(copy->y_size, sizeof(String));
for (size_t i = 0; i < copy->y_size; i++) {
- copy->y_array[i] = xstrdup(reg->y_array[i]);
+ copy->y_array[i] = copy_string(reg->y_array[i], NULL);
}
}
return copy;
@@ -1129,23 +1138,24 @@ static int stuff_yank(int regname, char *p)
xfree(p);
return OK;
}
+
+ const size_t plen = strlen(p);
yankreg_T *reg = get_yank_register(regname, YREG_YANK);
if (is_append_register(regname) && reg->y_array != NULL) {
- char **pp = &(reg->y_array[reg->y_size - 1]);
- const size_t ppl = strlen(*pp);
- const size_t pl = strlen(p);
- char *lp = xmalloc(ppl + pl + 1);
- memcpy(lp, *pp, ppl);
- memcpy(lp + ppl, p, pl);
- *(lp + ppl + pl) = NUL;
+ String *pp = &(reg->y_array[reg->y_size - 1]);
+ const size_t tmplen = pp->size + plen;
+ char *tmp = xmalloc(tmplen + 1);
+ memcpy(tmp, pp->data, pp->size);
+ memcpy(tmp + pp->size, p, plen);
+ *(tmp + tmplen) = NUL;
xfree(p);
- xfree(*pp);
- *pp = lp;
+ xfree(pp->data);
+ *pp = cbuf_as_string(tmp, tmplen);
} else {
free_register(reg);
reg->additional_data = NULL;
- reg->y_array = xmalloc(sizeof(char *));
- reg->y_array[0] = p;
+ reg->y_array = xmalloc(sizeof(String));
+ reg->y_array[0] = cbuf_as_string(p, plen);
reg->y_size = 1;
reg->y_type = kMTCharWise;
}
@@ -1169,7 +1179,7 @@ static int execreg_lastc = NUL;
/// with a \. Lines that start with a comment "\ character are ignored.
/// @returns the concatenated line. The index of the line that should be
/// processed next is returned in idx.
-static char *execreg_line_continuation(char **lines, size_t *idx)
+static char *execreg_line_continuation(String *lines, size_t *idx)
{
size_t i = *idx;
assert(i > 0);
@@ -1182,7 +1192,7 @@ static char *execreg_line_continuation(char **lines, size_t *idx)
// Any line not starting with \ or "\ is the start of the
// command.
while (--i > 0) {
- char *p = skipwhite(lines[i]);
+ char *p = skipwhite(lines[i].data);
if (*p != '\\' && (p[0] != '"' || p[1] != '\\' || p[2] != ' ')) {
break;
}
@@ -1190,9 +1200,9 @@ static char *execreg_line_continuation(char **lines, size_t *idx)
const size_t cmd_start = i;
// join all the lines
- ga_concat(&ga, lines[cmd_start]);
+ ga_concat(&ga, lines[cmd_start].data);
for (size_t j = cmd_start + 1; j <= cmd_end; j++) {
- char *p = skipwhite(lines[j]);
+ char *p = skipwhite(lines[j].data);
if (*p == '\\') {
// Adjust the growsize to the current length to
// speed up concatenating many lines.
@@ -1203,7 +1213,7 @@ static char *execreg_line_continuation(char **lines, size_t *idx)
}
}
ga_append(&ga, NUL);
- char *str = xstrdup(ga.ga_data);
+ char *str = xmemdupz(ga.ga_data, (size_t)ga.ga_len);
ga_clear(&ga);
*idx = i;
@@ -1296,7 +1306,7 @@ int do_execreg(int regname, int colon, int addcr, int silent)
}
// Handle line-continuation for :@<register>
- char *str = reg->y_array[i];
+ char *str = reg->y_array[i].data;
bool free_str = false;
if (colon && i > 0) {
char *p = skipwhite(str);
@@ -1434,7 +1444,7 @@ int insert_reg(int regname, bool literally_arg)
if (u_save_cursor() == FAIL) {
return FAIL;
}
- del_chars(mb_charlen(reg->y_array[0]), true);
+ del_chars(mb_charlen(reg->y_array[0].data), true);
curpos = curwin->w_cursor;
if (oneright() == FAIL) {
// hit end of line, need to put forward (after the current position)
@@ -1447,7 +1457,7 @@ int insert_reg(int regname, bool literally_arg)
AppendCharToRedobuff(regname);
do_put(regname, NULL, dir, 1, PUT_CURSEND);
} else {
- stuffescaped(reg->y_array[i], literally);
+ stuffescaped(reg->y_array[i].data, literally);
}
// Insert a newline between lines and after last line if
// y_type is kMTLineWise.
@@ -1494,7 +1504,7 @@ static dict_T* yankreg_to_dict(yankreg_T* yankreg) {
size_t i;
for (i = 0; i < yankreg->y_size; ++ i) {
tv_list_append_string(
- lines, yankreg->y_array[i], (long)strlen(yankreg->y_array[i]));
+ lines, yankreg->y_array[i].data, (long)yankreg->y_array[i].size);
}
tv_dict_add_list(dict, S_LEN("lines"), lines);
@@ -1657,7 +1667,7 @@ bool cmdline_paste_reg(int regname, bool literally_arg, bool remcr)
}
for (size_t i = 0; i < reg->y_size; i++) {
- cmdline_paste_str(reg->y_array[i], literally);
+ cmdline_paste_str(reg->y_array[i].data, literally);
// Insert ^M between lines, unless `remcr` is true.
if (i < reg->y_size - 1 && !remcr) {
@@ -2786,7 +2796,7 @@ void free_register(yankreg_T *reg)
}
for (size_t i = reg->y_size; i-- > 0;) { // from y_size - 1 to 0 included
- xfree(reg->y_array[i]);
+ API_CLEAR_STRING(reg->y_array[i]);
}
XFREE_CLEAR(reg->y_array);
}
@@ -2823,7 +2833,6 @@ bool op_yank(oparg_T *oap, bool message)
set_clipboard(oap->regname, reg);
do_autocmd_textyankpost(oap, reg);
-
return true;
}
@@ -2859,7 +2868,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
reg->y_size = yanklines;
reg->y_type = yank_type; // set the yank register type
reg->y_width = 0;
- reg->y_array = xcalloc(yanklines, sizeof(char *));
+ reg->y_array = xcalloc(yanklines, sizeof(String));
reg->additional_data = NULL;
reg->timestamp = os_time();
@@ -2883,11 +2892,16 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
break;
case kMTLineWise:
- reg->y_array[y_idx] = xstrdup(ml_get(lnum));
+ reg->y_array[y_idx] = cbuf_to_string(ml_get(lnum), (size_t)ml_get_len(lnum));
break;
case kMTCharWise:
charwise_block_prep(oap->start, oap->end, &bd, lnum, oap->inclusive);
+ // make sure bd.textlen is not longer than the text
+ int tmp = (int)strlen(bd.textstart);
+ if (tmp < bd.textlen) {
+ bd.textlen = tmp;
+ }
yank_copy_line(reg, &bd, y_idx, false);
break;
@@ -2899,7 +2913,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
if (curr != reg) { // append the new block to the old block
size_t j;
- char **new_ptr = xmalloc(sizeof(char *) * (curr->y_size + reg->y_size));
+ String *new_ptr = xmalloc(sizeof(String) * (curr->y_size + reg->y_size));
for (j = 0; j < curr->y_size; j++) {
new_ptr[j] = curr->y_array[j];
}
@@ -2915,13 +2929,16 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
// the new block, unless being Vi compatible.
if (curr->y_type == kMTCharWise
&& vim_strchr(p_cpo, CPO_REGAPPEND) == NULL) {
- char *pnew = xmalloc(strlen(curr->y_array[curr->y_size - 1])
- + strlen(reg->y_array[0]) + 1);
- STRCPY(pnew, curr->y_array[--j]);
- strcat(pnew, reg->y_array[0]);
- xfree(curr->y_array[j]);
- xfree(reg->y_array[0]);
- curr->y_array[j++] = pnew;
+ char *pnew = xmalloc(curr->y_array[curr->y_size - 1].size
+ + reg->y_array[0].size + 1);
+ j--;
+ STRCPY(pnew, curr->y_array[j].data);
+ STRCPY(pnew + curr->y_array[j].size, reg->y_array[0].data);
+ xfree(curr->y_array[j].data);
+ curr->y_array[j] = cbuf_as_string(pnew,
+ curr->y_array[j].size + reg->y_array[0].size);
+ j++;
+ API_CLEAR_STRING(reg->y_array[0]);
y_idx = 1;
} else {
y_idx = 0;
@@ -2992,7 +3009,7 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx,
int size = bd->startspaces + bd->endspaces + bd->textlen;
assert(size >= 0);
char *pnew = xmallocz((size_t)size);
- reg->y_array[y_idx] = pnew;
+ reg->y_array[y_idx].data = pnew;
memset(pnew, ' ', (size_t)bd->startspaces);
pnew += bd->startspaces;
memmove(pnew, bd->textstart, (size_t)bd->textlen);
@@ -3008,6 +3025,7 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx,
}
}
*pnew = NUL;
+ reg->y_array[y_idx].size = (size_t)(pnew - reg->y_array[y_idx].data);
}
/// Execute autocommands for TextYankPost.
@@ -3034,7 +3052,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
// The yanked text contents.
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
for (size_t i = 0; i < reg->y_size; i++) {
- tv_list_append_string(list, reg->y_array[i], -1);
+ tv_list_append_string(list, reg->y_array[i].data, -1);
}
tv_list_set_lock(list, VAR_FIXED);
tv_dict_add_list(dict, S_LEN("regcontents"), list);
@@ -3096,7 +3114,7 @@ static void do_autocmd_textput(int regname, yankreg_T *reg, enum auto_event evt)
// The yanked text contents.
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
for (size_t i = 0; i < reg->y_size; i++) {
- tv_list_append_string(list, (const char *)reg->y_array[i], -1);
+ tv_list_append_string(list, reg->y_array[i].data, reg->y_array[i].size);
}
tv_list_set_lock(list, VAR_FIXED);
(void)tv_dict_add_list(dict, S_LEN("regcontents"), list);
@@ -3138,16 +3156,8 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
size_t y_size;
int y_width = 0;
colnr_T vcol = 0;
- int incr = 0;
- struct block_def bd;
- char **y_array = NULL;
+ String *y_array = NULL;
linenr_T nr_lines = 0;
- int indent;
- int orig_indent = 0; // init for gcc
- int indent_diff = 0; // init for gcc
- bool first_indent = true;
- int lendiff = 0;
- char *insert_string = NULL;
bool allocated = false;
const pos_T orig_start = curbuf->b_op_start;
const pos_T orig_end = curbuf->b_op_end;
@@ -3157,10 +3167,6 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
do_autocmd_textput(regname, reg, EVENT_TEXTPUTPRE);
}
- if (flags & PUT_FIXINDENT) {
- orig_indent = get_indent();
- }
-
curbuf->b_op_start = curwin->w_cursor; // default for '[ mark
curbuf->b_op_end = curwin->w_cursor; // default for '] mark
@@ -3248,8 +3254,9 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
// For special registers '%' (file name), '#' (alternate file name) and
// ':' (last command line), etc. we have to create a fake yank register.
- if (!reg && get_spec_reg(regname, &insert_string, &allocated, true)) {
- if (insert_string == NULL) {
+ String insert_string = STRING_INIT;
+ if (!reg && get_spec_reg(regname, &insert_string.data, &allocated, true)) {
+ if (insert_string.data == NULL) {
return;
}
}
@@ -3262,7 +3269,8 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
}
}
- if (insert_string != NULL) {
+ if (insert_string.data != NULL) {
+ insert_string.size = strlen(insert_string.data);
y_type = kMTCharWise;
if (regname == '=') {
// For the = register we need to split the string at NL
@@ -3270,29 +3278,37 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
// Loop twice: count the number of lines and save them.
while (true) {
y_size = 0;
- char *ptr = insert_string;
+ char *ptr = insert_string.data;
+ size_t ptrlen = insert_string.size;
while (ptr != NULL) {
if (y_array != NULL) {
- y_array[y_size] = ptr;
+ y_array[y_size].data = ptr;
}
y_size++;
- ptr = vim_strchr(ptr, '\n');
- if (ptr != NULL) {
+ char *tmp = vim_strchr(ptr, '\n');
+ if (tmp == NULL) {
if (y_array != NULL) {
- *ptr = NUL;
+ y_array[y_size - 1].size = ptrlen;
}
- ptr++;
+ } else {
+ if (y_array != NULL) {
+ *tmp = NUL;
+ y_array[y_size - 1].size = (size_t)(tmp - ptr);
+ ptrlen -= y_array[y_size - 1].size + 1;
+ }
+ tmp++;
// A trailing '\n' makes the register linewise.
- if (*ptr == NUL) {
+ if (*tmp == NUL) {
y_type = kMTLineWise;
break;
}
}
+ ptr = tmp;
}
if (y_array != NULL) {
break;
}
- y_array = xmalloc(y_size * sizeof(char *));
+ y_array = xmalloc(y_size * sizeof(String));
}
} else {
y_size = 1; // use fake one-line yank register
@@ -3330,14 +3346,16 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
goto end;
}
char *curline = get_cursor_line_ptr();
- char *p = curline + curwin->w_cursor.col;
+ char *p = get_cursor_pos_ptr();
+ char *const p_orig = p;
+ const size_t plen = (size_t)get_cursor_pos_len();
if (dir == FORWARD && *p != NUL) {
MB_PTR_ADV(p);
}
// we need this later for the correct extmark_splice() event
split_pos = (colnr_T)(p - curline);
- char *ptr = xstrdup(p);
+ char *ptr = xmemdupz(p, plen - (size_t)(p - p_orig));
ml_append(curwin->w_cursor.lnum, ptr, 0, false);
xfree(ptr);
@@ -3401,8 +3419,6 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
goto end;
}
- int yanklen = (int)strlen(y_array[0]);
-
if (cur_ve_flags == VE_ALL && y_type == kMTCharWise) {
if (gchar_cursor() == TAB) {
int viscol = getviscol();
@@ -3426,6 +3442,8 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
// Block mode
if (y_type == kMTBlockWise) {
+ int incr = 0;
+ struct block_def bd;
int c = gchar_cursor();
colnr_T endcol2 = 0;
@@ -3518,14 +3536,14 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
}
}
- yanklen = (int)strlen(y_array[i]);
+ const int yanklen = (int)y_array[i].size;
if ((flags & PUT_BLOCK_INNER) == 0) {
// calculate number of spaces required to fill right side of block
spaces = y_width + 1;
- cstype = init_charsize_arg(&csarg, curwin, 0, y_array[i]);
- ci = utf_ptr2StrCharInfo(y_array[i]);
+ cstype = init_charsize_arg(&csarg, curwin, 0, y_array[i].data);
+ ci = utf_ptr2StrCharInfo(y_array[i].data);
while (*ci.ptr != NUL) {
spaces -= win_charsize(cstype, 0, ci.ptr, ci.chr.value, &csarg).width;
ci = utfc_next(ci);
@@ -3556,7 +3574,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
// insert the new text
for (int j = 0; j < count; j++) {
- memmove(ptr, y_array[i], (size_t)yanklen);
+ memmove(ptr, y_array[i].data, (size_t)yanklen);
ptr += yanklen;
// insert block's trailing spaces only if there's text behind
@@ -3608,6 +3626,8 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
curwin->w_cursor.lnum = lnum;
}
} else {
+ const int yanklen = (int)y_array[0].size;
+
// Character or Line mode
if (y_type == kMTCharWise) {
// if type is kMTCharWise, FORWARD is the same as BACKWARD on the next
@@ -3680,10 +3700,10 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
memmove(newp, oldp, (size_t)col);
char *ptr = newp + col;
for (size_t i = 0; i < (size_t)count; i++) {
- memmove(ptr, y_array[0], (size_t)yanklen);
+ memmove(ptr, y_array[0].data, (size_t)yanklen);
ptr += yanklen;
}
- STRMOVE(ptr, oldp + col);
+ memmove(ptr, oldp + col, (size_t)(oldlen - col) + 1); // +1 for NUL
ml_replace(lnum, newp, false);
// compute the byte offset for the last character
@@ -3721,6 +3741,15 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
}
} else {
linenr_T new_lnum = new_cursor.lnum;
+ int indent;
+ int orig_indent = 0;
+ int indent_diff = 0; // init for gcc
+ bool first_indent = true;
+ int lendiff = 0;
+
+ if (flags & PUT_FIXINDENT) {
+ orig_indent = get_indent();
+ }
// Insert at least one line. When y_type is kMTCharWise, break the first
// line in two.
@@ -3732,10 +3761,11 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
// Then append y_array[0] to first line.
lnum = new_cursor.lnum;
char *ptr = ml_get(lnum) + col;
- totlen = strlen(y_array[y_size - 1]);
- char *newp = xmalloc((size_t)ml_get_len(lnum) - (size_t)col + totlen + 1);
- STRCPY(newp, y_array[y_size - 1]);
- strcat(newp, ptr);
+ size_t ptrlen = (size_t)ml_get_len(lnum) - (size_t)col;
+ totlen = y_array[y_size - 1].size;
+ char *newp = xmalloc(ptrlen + totlen + 1);
+ STRCPY(newp, y_array[y_size - 1].data);
+ STRCPY(newp + totlen, ptr);
// insert second line
ml_append(lnum, newp, 0, false);
new_lnum++;
@@ -3746,7 +3776,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
// copy first part of line
memmove(newp, oldp, (size_t)col);
// append to first line
- memmove(newp + col, y_array[0], (size_t)yanklen + 1);
+ memmove(newp + col, y_array[0].data, (size_t)yanklen + 1);
ml_replace(lnum, newp, false);
curwin->w_cursor.lnum = lnum;
@@ -3755,7 +3785,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
for (; i < y_size; i++) {
if ((y_type != kMTCharWise || i < y_size - 1)) {
- if (ml_append(lnum, y_array[i], 0, false) == FAIL) {
+ if (ml_append(lnum, y_array[i].data, 0, false) == FAIL) {
goto error;
}
new_lnum++;
@@ -3794,9 +3824,9 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
if (y_type == kMTCharWise
|| (y_type == kMTLineWise && (flags & PUT_LINE_SPLIT))) {
for (i = 0; i < y_size - 1; i++) {
- totsize += (bcount_t)strlen(y_array[i]) + 1;
+ totsize += (bcount_t)y_array[i].size + 1;
}
- lastsize = (int)strlen(y_array[y_size - 1]);
+ lastsize = (int)y_array[y_size - 1].size;
totsize += lastsize;
}
if (y_type == kMTCharWise) {
@@ -3840,13 +3870,13 @@ error:
// Put the '] mark on the first byte of the last inserted character.
// Correct the length for change in indent.
curbuf->b_op_end.lnum = new_lnum;
- size_t len = strlen(y_array[y_size - 1]);
- col = (colnr_T)len - lendiff;
+ col = (colnr_T)y_array[y_size - 1].size - lendiff;
if (col > 1) {
curbuf->b_op_end.col = col - 1;
- if (len > 0) {
- curbuf->b_op_end.col -= utf_head_off(y_array[y_size - 1],
- y_array[y_size - 1] + len - 1);
+ if (y_array[y_size - 1].size > 0) {
+ curbuf->b_op_end.col -= utf_head_off(y_array[y_size - 1].data,
+ y_array[y_size - 1].data
+ + y_array[y_size - 1].size - 1);
}
} else {
curbuf->b_op_end.col = 0;
@@ -3908,7 +3938,7 @@ end:
curbuf->b_op_end = orig_end;
}
if (allocated) {
- xfree(insert_string);
+ xfree(insert_string.data);
}
if (regname == '=') {
xfree(y_array);
@@ -3989,7 +4019,7 @@ void ex_display(exarg_T *eap)
if (arg != NULL && *arg == NUL) {
arg = NULL;
}
- int attr = HL_ATTR(HLF_8);
+ int hl_id = HLF_8;
// Highlight title
msg_puts_title(_("\nType Name Content"));
@@ -4030,7 +4060,7 @@ void ex_display(exarg_T *eap)
bool do_show = false;
for (size_t j = 0; !do_show && j < yb->y_size; j++) {
- do_show = !message_filtered(yb->y_array[j]);
+ do_show = !message_filtered(yb->y_array[j].data);
}
if (do_show || yb->y_size == 0) {
@@ -4045,18 +4075,18 @@ void ex_display(exarg_T *eap)
int n = Columns - 11;
for (size_t j = 0; j < yb->y_size && n > 1; j++) {
if (j) {
- msg_puts_attr("^J", attr);
+ msg_puts_hl("^J", hl_id, false);
n -= 2;
}
- for (p = yb->y_array[j];
+ for (p = yb->y_array[j].data;
*p != NUL && (n -= ptr2cells(p)) >= 0; p++) {
int clen = utfc_ptr2len(p);
- msg_outtrans_len(p, clen, 0);
+ msg_outtrans_len(p, clen, 0, false);
p += clen - 1;
}
}
if (n > 1 && yb->y_type == kMTLineWise) {
- msg_puts_attr("^J", attr);
+ msg_puts_hl("^J", hl_id, false);
}
}
os_breakcheck();
@@ -4126,10 +4156,10 @@ static void dis_msg(const char *p, bool skip_esc)
&& (n -= ptr2cells(p)) >= 0) {
int l;
if ((l = utfc_ptr2len(p)) > 1) {
- msg_outtrans_len(p, l, 0);
+ msg_outtrans_len(p, l, 0, false);
p += l;
} else {
- msg_outtrans_len(p++, 1, 0);
+ msg_outtrans_len(p++, 1, 0, false);
}
}
os_breakcheck();
@@ -5207,7 +5237,7 @@ void *get_reg_contents(int regname, int flags)
if (flags & kGRegList) {
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
for (size_t i = 0; i < reg->y_size; i++) {
- tv_list_append_string(list, reg->y_array[i], -1);
+ tv_list_append_string(list, reg->y_array[i].data, -1);
}
return list;
@@ -5216,9 +5246,8 @@ void *get_reg_contents(int regname, int flags)
// Compute length of resulting string.
size_t len = 0;
for (size_t i = 0; i < reg->y_size; i++) {
- len += strlen(reg->y_array[i]);
- // Insert a newline between lines and after last line if
- // y_type is kMTLineWise.
+ len += reg->y_array[i].size;
+ // Insert a newline between lines and after last line if y_type is kMTLineWise.
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
len++;
}
@@ -5229,11 +5258,10 @@ void *get_reg_contents(int regname, int flags)
// Copy the lines of the yank register into the string.
len = 0;
for (size_t i = 0; i < reg->y_size; i++) {
- STRCPY(retval + len, reg->y_array[i]);
- len += strlen(retval + len);
+ STRCPY(retval + len, reg->y_array[i].data);
+ len += reg->y_array[i].size;
- // Insert a NL between lines and after the last line if y_type is
- // kMTLineWise.
+ // Insert a newline between lines and after the last line if y_type is kMTLineWise.
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
retval[len++] = '\n';
}
@@ -5355,8 +5383,7 @@ void write_reg_contents_ex(int name, const char *str, ssize_t len, bool must_app
semsg(_(e_nobufnr), (int64_t)num);
}
} else {
- buf = buflist_findnr(buflist_findpat(str, str + strlen(str),
- true, false, false));
+ buf = buflist_findnr(buflist_findpat(str, str + len, true, false, false));
}
if (buf == NULL) {
return;
@@ -5452,7 +5479,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str,
}
// Grow the register array to hold the pointers to the new lines.
- char **pp = xrealloc(y_ptr->y_array, (y_ptr->y_size + newlines) * sizeof(char *));
+ String *pp = xrealloc(y_ptr->y_array, (y_ptr->y_size + newlines) * sizeof(String));
y_ptr->y_array = pp;
size_t lnum = y_ptr->y_size; // The current line number.
@@ -5464,7 +5491,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str,
if (str_list) {
for (char **ss = (char **)str; *ss != NULL; ss++, lnum++) {
size_t ss_len = strlen(*ss);
- pp[lnum] = xmemdupz(*ss, ss_len);
+ pp[lnum] = cbuf_to_string(*ss, ss_len);
maxlen = MAX(maxlen, ss_len);
}
} else {
@@ -5477,22 +5504,22 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str,
maxlen = MAX(maxlen, line_len);
// When appending, copy the previous line and free it after.
- size_t extra = append ? strlen(pp[--lnum]) : 0;
+ size_t extra = append ? pp[--lnum].size : 0;
char *s = xmallocz(line_len + extra);
if (extra > 0) {
- memcpy(s, pp[lnum], extra);
+ memcpy(s, pp[lnum].data, extra);
}
memcpy(s + extra, start, line_len);
size_t s_len = extra + line_len;
if (append) {
- xfree(pp[lnum]);
+ xfree(pp[lnum].data);
append = false; // only first line is appended
}
- pp[lnum] = s;
+ pp[lnum] = cbuf_as_string(s, s_len);
// Convert NULs to '\n' to prevent truncation.
- memchrsub(pp[lnum], NUL, '\n', s_len);
+ memchrsub(pp[lnum].data, NUL, '\n', s_len);
}
}
y_ptr->y_type = yank_type;
@@ -6783,7 +6810,7 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines)
void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust)
{
- if (reg->y_size > 0 && strlen(reg->y_array[reg->y_size - 1]) == 0) {
+ if (reg->y_size > 0 && reg->y_array[reg->y_size - 1].size == 0) {
// a known-to-be charwise yank might have a final linebreak
// but otherwise there is no line after the final newline
if (reg->y_type != kMTCharWise) {
@@ -6803,7 +6830,7 @@ void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust)
if (reg->y_type == kMTBlockWise) {
size_t maxlen = 0;
for (size_t i = 0; i < reg->y_size; i++) {
- size_t rowlen = strlen(reg->y_array[i]);
+ size_t rowlen = reg->y_array[i].size;
maxlen = MAX(maxlen, rowlen);
}
assert(maxlen <= INT_MAX);
@@ -6873,7 +6900,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
reg->y_type = kMTUnknown;
}
- reg->y_array = xcalloc((size_t)tv_list_len(lines), sizeof(char *));
+ reg->y_array = xcalloc((size_t)tv_list_len(lines), sizeof(String));
reg->y_size = (size_t)tv_list_len(lines);
reg->additional_data = NULL;
reg->timestamp = 0;
@@ -6885,14 +6912,15 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
goto err;
}
- reg->y_array[tv_idx++] = xstrdupnul(TV_LIST_ITEM_TV(li)->vval.v_string);
+ const char *s = TV_LIST_ITEM_TV(li)->vval.v_string;
+ reg->y_array[tv_idx++] = cstr_to_string(s != NULL ? s : "");
});
- if (reg->y_size > 0 && strlen(reg->y_array[reg->y_size - 1]) == 0) {
+ if (reg->y_size > 0 && reg->y_array[reg->y_size - 1].size == 0) {
// a known-to-be charwise yank might have a final linebreak
// but otherwise there is no line after the final newline
if (reg->y_type != kMTCharWise) {
- xfree(reg->y_array[reg->y_size - 1]);
+ xfree(reg->y_array[reg->y_size - 1].data);
reg->y_size--;
if (reg->y_type == kMTUnknown) {
reg->y_type = kMTLineWise;
@@ -6907,7 +6935,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
if (reg->y_type == kMTBlockWise) {
size_t maxlen = 0;
for (size_t i = 0; i < reg->y_size; i++) {
- size_t rowlen = strlen(reg->y_array[i]);
+ size_t rowlen = reg->y_array[i].size;
maxlen = MAX(maxlen, rowlen);
}
assert(maxlen <= INT_MAX);
@@ -6920,7 +6948,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
err:
if (reg->y_array) {
for (size_t i = 0; i < reg->y_size; i++) {
- xfree(reg->y_array[i]);
+ xfree(reg->y_array[i].data);
}
xfree(reg->y_array);
}
@@ -6944,7 +6972,7 @@ static void set_clipboard(int name, yankreg_T *reg)
list_T *const lines = tv_list_alloc((ptrdiff_t)reg->y_size + (reg->y_type != kMTCharWise));
for (size_t i = 0; i < reg->y_size; i++) {
- tv_list_append_string(lines, reg->y_array[i], -1);
+ tv_list_append_string(lines, reg->y_array[i].data, -1);
}
char regtype;
@@ -7028,7 +7056,7 @@ static inline bool reg_empty(const yankreg_T *const reg)
|| reg->y_size == 0
|| (reg->y_size == 1
&& reg->y_type == kMTCharWise
- && *(reg->y_array[0]) == NUL));
+ && reg->y_array[0].size == 0));
}
/// Iterate over global registers.