Patch 7.4a.043
Problem:    More ml_get errors when adding or deleting lines from Python.
            (Vlad Irnov)
Solution:   Switch to a window with the buffer when possible.
Files:      src/if_py_both.h


*** ../vim-7.4a.042/src/if_py_both.h    2013-07-17 17:15:20.000000000 +0200
--- src/if_py_both.h    2013-07-24 17:09:19.000000000 +0200
***************
*** 3695,3700 ****
--- 3695,3733 ----
  }
  
  /*
+  * Find a window that contains "buf" and switch to it.
+  * If there is no such window, use the current window and change "curbuf".
+  * Caller must initialize save_curbuf to NULL.
+  * restore_win_for_buf() MUST be called later!
+  */
+     static void
+ switch_to_win_for_buf(
+     buf_T     *buf,
+     win_T     **save_curwinp,
+     tabpage_T **save_curtabp,
+     buf_T     **save_curbufp)
+ {
+     win_T     *wp;
+     tabpage_T *tp;
+ 
+     if (find_win_for_buf(buf, &wp, &tp) == FAIL
+           || switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL)
+       switch_buffer(save_curbufp, buf);
+ }
+ 
+     static void
+ restore_win_for_buf(
+     win_T     *save_curwin,
+     tabpage_T *save_curtab,
+     buf_T     *save_curbuf)
+ {
+     if (save_curbuf == NULL)
+       restore_win(save_curwin, save_curtab, TRUE);
+     else
+       restore_buffer(save_curbuf);
+ }
+ 
+ /*
   * Replace a line in the specified buffer. The line number is
   * in Vim format (1-based). The replacement line is given as
   * a Python string object. The object is checked for validity
***************
*** 3706,3711 ****
--- 3739,3748 ----
      static int
  SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
  {
+     buf_T     *save_curbuf = NULL;
+     win_T     *save_curwin = NULL;
+     tabpage_T *save_curtab = NULL;
+ 
      /* First of all, we check the type of the supplied Python object.
       * There are three cases:
       *          1. NULL, or None - this is a deletion.
***************
*** 3714,3723 ****
       */
      if (line == Py_None || line == NULL)
      {
-       buf_T   *savebuf;
- 
        PyErr_Clear();
!       switch_buffer(&savebuf, buf);
  
        VimTryStart();
  
--- 3751,3758 ----
       */
      if (line == Py_None || line == NULL)
      {
        PyErr_Clear();
!       switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
  
        VimTryStart();
  
***************
*** 3727,3738 ****
            RAISE_DELETE_LINE_FAIL;
        else
        {
!           if (buf == savebuf)
                py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
!           deleted_lines_mark((linenr_T)n, 1L);
        }
  
!       restore_buffer(savebuf);
  
        if (VimTryEnd())
            return FAIL;
--- 3762,3776 ----
            RAISE_DELETE_LINE_FAIL;
        else
        {
!           if (buf == curbuf)
                py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
!           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. */
!               deleted_lines_mark((linenr_T)n, 1L);
        }
  
!       restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
  
        if (VimTryEnd())
            return FAIL;
***************
*** 3745,3751 ****
      else if (PyBytes_Check(line) || PyUnicode_Check(line))
      {
        char    *save = StringToLine(line);
-       buf_T   *savebuf;
  
        if (save == NULL)
            return FAIL;
--- 3783,3788 ----
***************
*** 3754,3760 ****
  
        /* We do not need to free "save" if ml_replace() consumes it. */
        PyErr_Clear();
!       switch_buffer(&savebuf, buf);
  
        if (u_savesub((linenr_T)n) == FAIL)
        {
--- 3791,3797 ----
  
        /* We do not need to free "save" if ml_replace() consumes it. */
        PyErr_Clear();
!       switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
  
        if (u_savesub((linenr_T)n) == FAIL)
        {
***************
*** 3769,3778 ****
        else
            changed_bytes((linenr_T)n, 0);
  
!       restore_buffer(savebuf);
  
        /* Check that the cursor is not beyond the end of the line now. */
!       if (buf == savebuf)
            check_cursor_col();
  
        if (VimTryEnd())
--- 3806,3815 ----
        else
            changed_bytes((linenr_T)n, 0);
  
!       restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
  
        /* Check that the cursor is not beyond the end of the line now. */
!       if (buf == curbuf)
            check_cursor_col();
  
        if (VimTryEnd())
***************
*** 3806,3811 ****
--- 3843,3852 ----
        PyObject *list,
        PyInt *len_change)
  {
+     buf_T     *save_curbuf = NULL;
+     win_T     *save_curwin = NULL;
+     tabpage_T *save_curtab = NULL;
+ 
      /* First of all, we check the type of the supplied Python object.
       * There are three cases:
       *          1. NULL, or None - this is a deletion.
***************
*** 3816,3826 ****
      {
        PyInt   i;
        PyInt   n = (int)(hi - lo);
-       buf_T   *savebuf;
  
        PyErr_Clear();
        VimTryStart();
!       switch_buffer(&savebuf, buf);
  
        if (u_savedel((linenr_T)lo, (long)n) == FAIL)
            RAISE_UNDO_FAIL;
--- 3857,3866 ----
      {
        PyInt   i;
        PyInt   n = (int)(hi - lo);
  
        PyErr_Clear();
        VimTryStart();
!       switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
  
        if (u_savedel((linenr_T)lo, (long)n) == FAIL)
            RAISE_UNDO_FAIL;
***************
*** 3834,3845 ****
                    break;
                }
            }
!           if (buf == savebuf)
                py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
!           deleted_lines_mark((linenr_T)lo, (long)i);
        }
  
!       restore_buffer(savebuf);
  
        if (VimTryEnd())
            return FAIL;
--- 3874,3888 ----
                    break;
                }
            }
!           if (buf == curbuf)
                py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
!           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. */
!               deleted_lines_mark((linenr_T)lo, (long)i);
        }
  
!       restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
  
        if (VimTryEnd())
            return FAIL;
***************
*** 3856,3862 ****
        PyInt   old_len = hi - lo;
        PyInt   extra = 0;      /* lines added to text, can be negative */
        char    **array;
-       buf_T   *savebuf;
  
        if (new_len == 0)       /* avoid allocating zero bytes */
            array = NULL;
--- 3899,3904 ----
***************
*** 3888,3894 ****
        PyErr_Clear();
  
        /* START of region without "return".  Must call restore_buffer()! */
!       switch_buffer(&savebuf, buf);
  
        if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
            RAISE_UNDO_FAIL;
--- 3930,3936 ----
        PyErr_Clear();
  
        /* START of region without "return".  Must call restore_buffer()! */
!       switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
  
        if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
            RAISE_UNDO_FAIL;
***************
*** 3960,3975 ****
  
        /* Adjust marks. Invalidate any which lie in the
         * changed range, and move any in the remainder of the buffer.
!        */
!       mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
                                                  (long)MAXLNUM, (long)extra);
        changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
  
!       if (buf == savebuf)
            py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
  
        /* END of region without "return". */
!       restore_buffer(savebuf);
  
        if (VimTryEnd())
            return FAIL;
--- 4002,4019 ----
  
        /* Adjust marks. Invalidate any which lie in the
         * changed range, and move any in the remainder of the buffer.
!        * Only adjust marks if we managed to switch to a window that holds
!        * the buffer, otherwise line numbers will be invalid. */
!       if (save_curbuf == NULL)
!           mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
                                                  (long)MAXLNUM, (long)extra);
        changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
  
!       if (buf == curbuf)
            py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
  
        /* END of region without "return". */
!       restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
  
        if (VimTryEnd())
            return FAIL;
***************
*** 3998,4006 ****
  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.
--- 4042,4048 ----
***************
*** 4015,4024 ****
  
        PyErr_Clear();
        VimTryStart();
!       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;
--- 4057,4063 ----
  
        PyErr_Clear();
        VimTryStart();
!       switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
  
        if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
            RAISE_UNDO_FAIL;
***************
*** 4030,4039 ****
            appended_lines_mark((linenr_T)n, 1L);
  
        vim_free(str);
!       if (save_curbuf == NULL)
!           restore_win(save_curwin, save_curtab, TRUE);
!       else
!           restore_buffer(save_curbuf);
        update_screen(VALID);
  
        if (VimTryEnd())
--- 4069,4075 ----
            appended_lines_mark((linenr_T)n, 1L);
  
        vim_free(str);
!       restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
        update_screen(VALID);
  
        if (VimTryEnd())
***************
*** 4073,4082 ****
  
        PyErr_Clear();
        VimTryStart();
!       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;
--- 4109,4115 ----
  
        PyErr_Clear();
        VimTryStart();
!       switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
  
        if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
            RAISE_UNDO_FAIL;
***************
*** 4097,4114 ****
                }
                vim_free(array[i]);
            }
!           if (i > 0)
                appended_lines_mark((linenr_T)n, (long)i);
        }
  
        /* Free the array of lines. All of its contents have now
         * been freed. */
        PyMem_Free(array);
  
-       if (save_curbuf == NULL)
-           restore_win(save_curwin, save_curtab, TRUE);
-       else
-           restore_buffer(save_curbuf);
        update_screen(VALID);
  
        if (VimTryEnd())
--- 4130,4146 ----
                }
                vim_free(array[i]);
            }
!           if (i > 0 && 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, (long)i);
        }
  
        /* Free the array of lines. All of its contents have now
         * been freed. */
        PyMem_Free(array);
+       restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
  
        update_screen(VALID);
  
        if (VimTryEnd())
*** ../vim-7.4a.042/src/version.c       2013-07-24 16:02:32.000000000 +0200
--- src/version.c       2013-07-24 17:05:23.000000000 +0200
***************
*** 729,730 ****
--- 729,732 ----
  {   /* Add new patch number below this line */
+ /**/
+     43,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
24. You realize there is not a sound in the house and you have no idea where
    your children are.

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Raspunde prin e-mail lui