diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 57b6b1b79a..6ef3a69b9a 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -2487,23 +2487,19 @@ void ml_add_deleted_len_buf(buf_T *buf, char *ptr, ssize_t len) } } +/// Replace line "lnum", with buffering, in current buffer. int ml_replace(linenr_T lnum, char *line, bool copy) { return ml_replace_buf(curbuf, lnum, line, copy, false); } -/// Replace line "lnum", with buffering, in current buffer. -/// -/// @param copy if true, make a copy of the line, otherwise the line has been -/// copied to allocated memory already. -/// if false, the "line" may be freed to add text properties! -/// -/// Do not use it after calling ml_replace(). -/// -/// Check: The caller of this function should probably also call -/// changed_lines(), unless update_screen(UPD_NOT_VALID) is used. -/// -/// @return FAIL for failure, OK otherwise +/// Replace a line for the current buffer. Like ml_replace() with: +/// "len" is the length of the text, excluding NUL. +int ml_replace_len(linenr_T lnum, char *line, size_t len, bool copy) +{ + return ml_replace_buf_len(curbuf, lnum, line, len, copy, false); +} + int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy, bool noalloc) FUNC_ATTR_NONNULL_ARG(1) { @@ -2511,6 +2507,19 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy, bool noallo return ml_replace_buf_len(buf, lnum, line, len, copy, noalloc); } +/// Replace line "lnum", with buffering. +/// +/// @param copy if true, make a copy of the line, otherwise the line has been +/// copied to allocated memory already. +/// if false, the "line" may be freed to add text properties! +/// @param len_arg length of the text, excluding NUL +/// +/// Do not use it after calling ml_replace(). +/// +/// Check: The caller of this function should probably also call +/// changed_lines(), unless update_screen(UPD_NOT_VALID) is used. +/// +/// @return FAIL for failure, OK otherwise int ml_replace_buf_len(buf_T *buf, linenr_T lnum, char *line_arg, size_t len_arg, bool copy, bool noalloc) FUNC_ATTR_NONNULL_ARG(1) diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 61f94172e2..25dd40a793 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4014,9 +4014,9 @@ int do_join(size_t count, bool insert_space, bool save_undo, bool use_formatopti colnr_T col = sumsize - currsize - spaces[count - 1]; // allocate the space for the new line - char *newp = xmalloc((size_t)sumsize + 1); + size_t newp_len = (size_t)sumsize; + char *newp = xmallocz(newp_len); cend = newp + sumsize; - *cend = 0; // Move affected lines to the new long one. // This loops backwards over the joined lines, including the original line. @@ -4030,6 +4030,7 @@ int do_join(size_t count, bool insert_space, bool save_undo, bool use_formatopti for (linenr_T t = (linenr_T)count - 1;; t--) { cend -= currsize; memmove(cend, curr, (size_t)currsize); + if (spaces[t] > 0) { cend -= spaces[t]; memset(cend, ' ', (size_t)(spaces[t])); @@ -4060,7 +4061,7 @@ int do_join(size_t count, bool insert_space, bool save_undo, bool use_formatopti currsize = (int)strlen(curr); } - ml_replace(curwin->w_cursor.lnum, newp, false); + ml_replace_len(curwin->w_cursor.lnum, newp, newp_len, false); if (setmark && (cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) { // Set the '] mark.