Mercurial > vim
changeset 5202:8edba3805d78 v7.4a.027
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.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 17 Jul 2013 17:15:25 +0200 |
parents | b2ed17f5d19c |
children | 72e04e0e326d |
files | src/if_py_both.h src/proto/buffer.pro src/version.c src/window.c |
diffstat | 4 files changed, 34 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- 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())
--- 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));
--- 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,
--- 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.