# HG changeset patch # User Bram Moolenaar # Date 1374074125 -7200 # Node ID 8edba3805d787f50b51d7fd59899c5361c09a348 # Parent b2ed17f5d19c46046beecc8331021357f73c4470 updated for version 7.4a.027 Problem: When Python adds lines to another buffer the cursor position is wrong, it might be below the last line causing ml_get errors. (Vlad Irnov) Solution: Temporarily change the current window, so that marks are corrected properly. diff --git a/src/if_py_both.h b/src/if_py_both.h --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -3997,30 +3997,43 @@ SetBufferLineList( static int InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change) { + buf_T *save_curbuf = NULL; + win_T *wp; + win_T *save_curwin = NULL; + tabpage_T *tp; + tabpage_T *save_curtab = NULL; + /* First of all, we check the type of the supplied Python object. * It must be a string or a list, or the call is in error. */ if (PyBytes_Check(lines) || PyUnicode_Check(lines)) { - char *str = StringToLine(lines); - buf_T *savebuf; + char *str = StringToLine(lines); if (str == NULL) return FAIL; PyErr_Clear(); VimTryStart(); - switch_buffer(&savebuf, buf); - - if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL) + if (find_win_for_buf(buf, &wp, &tp) == FAIL + || switch_win(&save_curwin, &save_curtab, wp, tp, TRUE) + == FAIL) + switch_buffer(&save_curbuf, buf); + + if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL) RAISE_UNDO_FAIL; else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL) RAISE_INSERT_LINE_FAIL; - else + else if (save_curbuf == NULL) + /* Only adjust marks if we managed to switch to a window that + * holds the buffer, otherwise line numbers will be invalid. */ appended_lines_mark((linenr_T)n, 1L); vim_free(str); - restore_buffer(savebuf); + if (save_curbuf == NULL) + restore_win(save_curwin, save_curtab, TRUE); + else + restore_buffer(save_curbuf); update_screen(VALID); if (VimTryEnd()) @@ -4036,7 +4049,6 @@ InsertBufferLines(buf_T *buf, PyInt n, P PyInt i; PyInt size = PyList_Size(lines); char **array; - buf_T *savebuf; array = PyMem_New(char *, size); if (array == NULL) @@ -4061,7 +4073,10 @@ InsertBufferLines(buf_T *buf, PyInt n, P PyErr_Clear(); VimTryStart(); - switch_buffer(&savebuf, buf); + if (find_win_for_buf(buf, &wp, &tp) == FAIL + || switch_win(&save_curwin, &save_curtab, wp, tp, TRUE) + == FAIL) + switch_buffer(&save_curbuf, buf); if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL) RAISE_UNDO_FAIL; @@ -4087,11 +4102,13 @@ InsertBufferLines(buf_T *buf, PyInt n, P } /* Free the array of lines. All of its contents have now - * been freed. - */ + * been freed. */ PyMem_Free(array); - restore_buffer(savebuf); + if (save_curbuf == NULL) + restore_win(save_curwin, save_curtab, TRUE); + else + restore_buffer(save_curbuf); update_screen(VALID); if (VimTryEnd()) diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro --- a/src/proto/buffer.pro +++ b/src/proto/buffer.pro @@ -52,6 +52,7 @@ void do_modelines __ARGS((int flags)); int read_viminfo_bufferlist __ARGS((vir_T *virp, int writing)); void write_viminfo_bufferlist __ARGS((FILE *fp)); char_u *buf_spname __ARGS((buf_T *buf)); +int find_win_for_buf __ARGS((buf_T *buf, win_T **wp, tabpage_T **tp)); void buf_addsign __ARGS((buf_T *buf, int id, linenr_T lnum, int typenr)); linenr_T buf_change_sign_type __ARGS((buf_T *buf, int markId, int typenr)); int buf_getsigntype __ARGS((buf_T *buf, linenr_T lnum, int type)); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -728,6 +728,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 27, +/**/ 26, /**/ 25, diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -6577,7 +6577,8 @@ restore_snapshot_rec(sn, fr) #endif -#if defined(FEAT_EVAL) || defined(PROTO) +#if defined(FEAT_EVAL) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ + || defined(PROTO) /* * Set "win" to be the curwin and "tp" to be the current tab page. * restore_win() MUST be called to undo.