diff options
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r-- | src/nvim/ops.c | 290 |
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. |