From d573ffcfc7dc7b4f80db8d5f5744e0ecabb26cff Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 10 Aug 2025 18:38:39 -0400 Subject: [PATCH] vim-patch:8.1.1700: listener callback called for the wrong buffer Problem: Listener callback called for the wrong buffer. Solution: Invoke listeners before calling ml_append_int(). https://github.com/vim/vim/commit/250e3112c6dc4c4ceded308d5b94392ec02bc03f Co-authored-by: Bram Moolenaar (cherry picked from commit c9b35360ac426d531afcb773c2be7946d804cefc) --- src/nvim/memline.c | 119 ++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 51 deletions(-) diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 384cd00c5a..6067413a43 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1971,61 +1971,16 @@ int ml_line_alloced(void) return curbuf->b_ml.ml_flags & ML_LINE_DIRTY; } -/// Append a line after lnum (may be 0 to insert a line in front of the file). -/// "line" does not need to be allocated, but can't be another line in a -/// buffer, unlocking may make it invalid. -/// -/// newfile: true when starting to edit a new file, meaning that pe_old_lnum -/// will be set for recovery -/// Check: The caller of this function should probably also call -/// appended_lines(). -/// -/// @param lnum append after this line (can be 0) -/// @param line text of the new line -/// @param len length of new line, including NUL, or 0 -/// @param newfile flag, see above -/// -/// @return FAIL for failure, OK otherwise -int ml_append(linenr_T lnum, char *line, colnr_T len, bool newfile) -{ - // When starting up, we might still need to create the memfile - if (curbuf->b_ml.ml_mfp == NULL && open_buffer(false, NULL, 0) == FAIL) { - return FAIL; - } - - if (curbuf->b_ml.ml_line_lnum != 0) { - ml_flush_line(curbuf, false); - } - return ml_append_int(curbuf, lnum, line, len, newfile, false); -} - -/// Like ml_append() but for an arbitrary buffer. The buffer must already have -/// a memline. -/// -/// @param lnum append after this line (can be 0) -/// @param line text of the new line -/// @param len length of new line, including NUL, or 0 -/// @param newfile flag, see above -int ml_append_buf(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile) - FUNC_ATTR_NONNULL_ARG(1) -{ - if (buf->b_ml.ml_mfp == NULL) { - return FAIL; - } - - if (buf->b_ml.ml_line_lnum != 0) { - ml_flush_line(buf, false); - } - return ml_append_int(buf, lnum, line, len, newfile, false); -} - /// @param lnum append after this line (can be 0) /// @param line text of the new line /// @param len length of line, including NUL, or 0 /// @param newfile flag, see above /// @param mark mark the new line +/// +/// @return FAIL for failure, OK otherwise static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile, bool mark) + FUNC_ATTR_NONNULL_ARG(1) { // lnum out of range if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) { @@ -2039,9 +1994,6 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo if (len == 0) { len = (colnr_T)strlen(line) + 1; // space needed for the text } - if (curbuf->b_ml.ml_line_lnum != 0) { - ml_flush_line(curbuf, false); - } int space_needed = len + (int)INDEX_SIZE; // space needed for text + index memfile_T *mfp = buf->b_ml.ml_mfp; @@ -2429,6 +2381,71 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo return OK; } +/// Flush any pending change and call ml_append_int() +/// +/// @param buf +/// @param lnum append after this line (can be 0) +/// @param line text of the new line +/// @param len length of line, including NUL, or 0 +/// @param newfile flag, see above +/// +/// @return FAIL for failure, OK otherwise +static int ml_append_flush(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile) + FUNC_ATTR_NONNULL_ARG(1) +{ + if (lnum > buf->b_ml.ml_line_count) { + return FAIL; // lnum out of range + } + if (buf->b_ml.ml_line_lnum != 0) { + // This may also invoke ml_append_int(). + ml_flush_line(buf, false); + } + + return ml_append_int(buf, lnum, line, len, newfile, false); +} + +/// Append a line after lnum (may be 0 to insert a line in front of the file). +/// "line" does not need to be allocated, but can't be another line in a +/// buffer, unlocking may make it invalid. +/// +/// newfile: true when starting to edit a new file, meaning that pe_old_lnum +/// will be set for recovery +/// Check: The caller of this function should probably also call +/// appended_lines(). +/// +/// @param lnum append after this line (can be 0) +/// @param line text of the new line +/// @param len length of new line, including NUL, or 0 +/// @param newfile flag, see above +/// +/// @return FAIL for failure, OK otherwise +int ml_append(linenr_T lnum, char *line, colnr_T len, bool newfile) +{ + // When starting up, we might still need to create the memfile + if (curbuf->b_ml.ml_mfp == NULL && open_buffer(false, NULL, 0) == FAIL) { + return FAIL; + } + + return ml_append_flush(curbuf, lnum, line, len, newfile); +} + +/// Like ml_append() but for an arbitrary buffer. The buffer must already have +/// a memline. +/// +/// @param lnum append after this line (can be 0) +/// @param line text of the new line +/// @param len length of new line, including NUL, or 0 +/// @param newfile flag, see above +int ml_append_buf(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile) + FUNC_ATTR_NONNULL_ARG(1) +{ + if (buf->b_ml.ml_mfp == NULL) { + return FAIL; + } + + return ml_append_flush(buf, lnum, line, len, newfile); +} + void ml_add_deleted_len(char *ptr, ssize_t len) { ml_add_deleted_len_buf(curbuf, ptr, len);