updated for version 7.4a.027 v7.4a.027
authorBram Moolenaar <Bram@vim.org>
Wed, 17 Jul 2013 15:15:25 +0000 (17:15 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 17 Jul 2013 15:15:25 +0000 (17:15 +0200)
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.

src/if_py_both.h
src/proto/buffer.pro
src/version.c
src/window.c

index 48b7be7bebcd4ca3a4a09cf23ae71e2bbe87a805..4ac2ebfad92ca57ae3f72f4b56baa1d4eaa92cf5 100644 (file)
@@ -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 (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)
+       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, PyObject *lines, PyInt *len_change)
        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, PyObject *lines, PyInt *len_change)
 
        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, PyObject *lines, PyInt *len_change)
        }
 
        /* 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())
index ad205c0b3c2bfd629dbfe52c404d1cacf69de7fd..9e97f67e444b8acac58f0be6665e6b9bfe1a7d5d 100644 (file)
@@ -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));
index eb48ddd257161ddf14b0da3d68dccc5e3431dac1..64325c2aec5f4ad92d5ce7e953ce6709b21f7ee5 100644 (file)
@@ -727,6 +727,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    27,
 /**/
     26,
 /**/
index 2435952e1574bb29918cf1e03111ef073891708c..28bb12547c1396202bf9588deea3652898cff28e 100644 (file)
@@ -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.