To:
[email protected]
Subject: Patch 7.4a.043
Fcc: outbox
From: Bram Moolenaar <
[email protected]>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------
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 --
[email protected] --
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 ///