diff options
-rw-r--r-- | src/nvim/log.h | 4 | ||||
-rw-r--r-- | src/nvim/ops.c | 29 | ||||
-rw-r--r-- | test/functional/lua/buffer_updates_spec.lua | 63 |
3 files changed, 68 insertions, 28 deletions
diff --git a/src/nvim/log.h b/src/nvim/log.h index 17ff095473..a6a4c78707 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -68,6 +68,10 @@ # define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) #endif +#if defined(__has_include) && __has_include("sanitizer/asan_interface.h") +# include "sanitizer/asan_interface.h" +#endif + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "log.h.generated.h" #endif diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 1f55d2c315..6209dd6492 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1544,10 +1544,10 @@ int op_delete(oparg_T *oap) oap->line_count = 0; // no lines deleted } else if (oap->motion_type == kMTLineWise) { if (oap->op_type == OP_CHANGE) { - /* Delete the lines except the first one. Temporarily move the - * cursor to the next line. Save the current line number, if the - * last line is deleted it may be changed. - */ + // Delete the lines except the first one. Temporarily move the + // cursor to the next line. Save the current line number, if the + // last line is deleted it may be changed. + if (oap->line_count > 1) { lnum = curwin->w_cursor.lnum; ++curwin->w_cursor.lnum; @@ -1560,12 +1560,21 @@ int op_delete(oparg_T *oap) beginline(BL_WHITE); // cursor on first non-white did_ai = true; // delete the indent when ESC hit ai_col = curwin->w_cursor.col; - } else - beginline(0); /* cursor in column 0 */ - truncate_line(FALSE); /* delete the rest of the line */ - /* leave cursor past last char in line */ - if (oap->line_count > 1) - u_clearline(); /* "U" command not possible after "2cc" */ + } else { + beginline(0); // cursor in column 0 + } + + int old_len = (int)STRLEN(ml_get(curwin->w_cursor.lnum)); + truncate_line(false); // delete the rest of the line + + extmark_splice_cols(curbuf, + (int)curwin->w_cursor.lnum-1, curwin->w_cursor.col, + old_len - curwin->w_cursor.col, 0, kExtmarkUndo); + + // leave cursor past last char in line + if (oap->line_count > 1) { + u_clearline(); // "U" command not possible after "2cc" + } } else { del_lines(oap->line_count, TRUE); beginline(BL_WHITE | BL_FIX); diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index ac5d25bdab..805e880663 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -287,26 +287,36 @@ describe('lua: nvim_buf_attach on_bytes', function() fail(msg) end - if verify then - for _, event in ipairs(events) do - if event[1] == verify_name and event[2] == "bytes" then - local _, _, _, _, _, _, start_byte, _, _, old_byte, _, _, new_byte = unpack(event) - local before = string.sub(shadowbytes, 1, start_byte) - -- no text in the tests will contain 0xff bytes (invalid UTF-8) - -- so we can use it as marker for unknown bytes - local unknown = string.rep('\255', new_byte) - local after = string.sub(shadowbytes, start_byte + old_byte + 1) - shadowbytes = before .. unknown .. after + if not verify then + return + end + + for _, event in ipairs(events) do + for _, elem in ipairs(event) do + if type(elem) == "number" and elem < 0 then + fail(string.format("Received event has negative values")) end end - local text = meths.buf_get_lines(0, 0, -1, true) - local bytes = table.concat(text, '\n') .. '\n' - eq(string.len(bytes), string.len(shadowbytes), '\non_bytes: total bytecount of buffer is wrong') - for i = 1, string.len(shadowbytes) do - local shadowbyte = string.sub(shadowbytes, i, i) - if shadowbyte ~= '\255' then - eq(string.sub(bytes, i, i), shadowbyte, i) - end + + if event[1] == verify_name and event[2] == "bytes" then + local _, _, _, _, _, _, start_byte, _, _, old_byte, _, _, new_byte = unpack(event) + local before = string.sub(shadowbytes, 1, start_byte) + -- no text in the tests will contain 0xff bytes (invalid UTF-8) + -- so we can use it as marker for unknown bytes + local unknown = string.rep('\255', new_byte) + local after = string.sub(shadowbytes, start_byte + old_byte + 1) + shadowbytes = before .. unknown .. after + end + end + + local text = meths.buf_get_lines(0, 0, -1, true) + local bytes = table.concat(text, '\n') .. '\n' + + eq(string.len(bytes), string.len(shadowbytes), '\non_bytes: total bytecount of buffer is wrong') + for i = 1, string.len(shadowbytes) do + local shadowbyte = string.sub(shadowbytes, i, i) + if shadowbyte ~= '\255' then + eq(string.sub(bytes, i, i), shadowbyte, i) end end end @@ -411,6 +421,23 @@ describe('lua: nvim_buf_attach on_bytes', function() { "test1", "bytes", 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; } end) + + it("changing lines", function() + local check_events = setup_eventcheck(verify, origlines) + + feed "cc" + check_events { + { "test1", "bytes", 1, 4, 0, 0, 0, 0, 15, 15, 0, 0, 0 }; + } + + feed "<ESC>" + check_events {} + + feed "c3j" + check_events { + { "test1", "bytes", 1, 4, 1, 0, 1, 3, 0, 48, 0, 0, 0 }; + } + end) end describe('(with verify) handles', function() |