comparison src/if_py_both.h @ 5235:6fa64615c8d3 v7.4a.043

updated for version 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.
author Bram Moolenaar <bram@vim.org>
date Wed, 24 Jul 2013 17:11:46 +0200
parents 8edba3805d78
children 9cedb4dfd4c8
comparison
equal deleted inserted replaced
5234:e0258a94f389 5235:6fa64615c8d3
3693 } 3693 }
3694 invalidate_botline(); 3694 invalidate_botline();
3695 } 3695 }
3696 3696
3697 /* 3697 /*
3698 * Find a window that contains "buf" and switch to it.
3699 * If there is no such window, use the current window and change "curbuf".
3700 * Caller must initialize save_curbuf to NULL.
3701 * restore_win_for_buf() MUST be called later!
3702 */
3703 static void
3704 switch_to_win_for_buf(
3705 buf_T *buf,
3706 win_T **save_curwinp,
3707 tabpage_T **save_curtabp,
3708 buf_T **save_curbufp)
3709 {
3710 win_T *wp;
3711 tabpage_T *tp;
3712
3713 if (find_win_for_buf(buf, &wp, &tp) == FAIL
3714 || switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL)
3715 switch_buffer(save_curbufp, buf);
3716 }
3717
3718 static void
3719 restore_win_for_buf(
3720 win_T *save_curwin,
3721 tabpage_T *save_curtab,
3722 buf_T *save_curbuf)
3723 {
3724 if (save_curbuf == NULL)
3725 restore_win(save_curwin, save_curtab, TRUE);
3726 else
3727 restore_buffer(save_curbuf);
3728 }
3729
3730 /*
3698 * Replace a line in the specified buffer. The line number is 3731 * Replace a line in the specified buffer. The line number is
3699 * in Vim format (1-based). The replacement line is given as 3732 * in Vim format (1-based). The replacement line is given as
3700 * a Python string object. The object is checked for validity 3733 * a Python string object. The object is checked for validity
3701 * and correct format. Errors are returned as a value of FAIL. 3734 * and correct format. Errors are returned as a value of FAIL.
3702 * The return value is OK on success. 3735 * The return value is OK on success.
3704 * is set to the change in the buffer length. 3737 * is set to the change in the buffer length.
3705 */ 3738 */
3706 static int 3739 static int
3707 SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change) 3740 SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
3708 { 3741 {
3742 buf_T *save_curbuf = NULL;
3743 win_T *save_curwin = NULL;
3744 tabpage_T *save_curtab = NULL;
3745
3709 /* First of all, we check the type of the supplied Python object. 3746 /* First of all, we check the type of the supplied Python object.
3710 * There are three cases: 3747 * There are three cases:
3711 * 1. NULL, or None - this is a deletion. 3748 * 1. NULL, or None - this is a deletion.
3712 * 2. A string - this is a replacement. 3749 * 2. A string - this is a replacement.
3713 * 3. Anything else - this is an error. 3750 * 3. Anything else - this is an error.
3714 */ 3751 */
3715 if (line == Py_None || line == NULL) 3752 if (line == Py_None || line == NULL)
3716 { 3753 {
3717 buf_T *savebuf;
3718
3719 PyErr_Clear(); 3754 PyErr_Clear();
3720 switch_buffer(&savebuf, buf); 3755 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
3721 3756
3722 VimTryStart(); 3757 VimTryStart();
3723 3758
3724 if (u_savedel((linenr_T)n, 1L) == FAIL) 3759 if (u_savedel((linenr_T)n, 1L) == FAIL)
3725 RAISE_UNDO_FAIL; 3760 RAISE_UNDO_FAIL;
3726 else if (ml_delete((linenr_T)n, FALSE) == FAIL) 3761 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
3727 RAISE_DELETE_LINE_FAIL; 3762 RAISE_DELETE_LINE_FAIL;
3728 else 3763 else
3729 { 3764 {
3730 if (buf == savebuf) 3765 if (buf == curbuf)
3731 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1); 3766 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
3732 deleted_lines_mark((linenr_T)n, 1L); 3767 if (save_curbuf == NULL)
3733 } 3768 /* Only adjust marks if we managed to switch to a window that
3734 3769 * holds the buffer, otherwise line numbers will be invalid. */
3735 restore_buffer(savebuf); 3770 deleted_lines_mark((linenr_T)n, 1L);
3771 }
3772
3773 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
3736 3774
3737 if (VimTryEnd()) 3775 if (VimTryEnd())
3738 return FAIL; 3776 return FAIL;
3739 3777
3740 if (len_change) 3778 if (len_change)
3743 return OK; 3781 return OK;
3744 } 3782 }
3745 else if (PyBytes_Check(line) || PyUnicode_Check(line)) 3783 else if (PyBytes_Check(line) || PyUnicode_Check(line))
3746 { 3784 {
3747 char *save = StringToLine(line); 3785 char *save = StringToLine(line);
3748 buf_T *savebuf;
3749 3786
3750 if (save == NULL) 3787 if (save == NULL)
3751 return FAIL; 3788 return FAIL;
3752 3789
3753 VimTryStart(); 3790 VimTryStart();
3754 3791
3755 /* We do not need to free "save" if ml_replace() consumes it. */ 3792 /* We do not need to free "save" if ml_replace() consumes it. */
3756 PyErr_Clear(); 3793 PyErr_Clear();
3757 switch_buffer(&savebuf, buf); 3794 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
3758 3795
3759 if (u_savesub((linenr_T)n) == FAIL) 3796 if (u_savesub((linenr_T)n) == FAIL)
3760 { 3797 {
3761 RAISE_UNDO_FAIL; 3798 RAISE_UNDO_FAIL;
3762 vim_free(save); 3799 vim_free(save);
3767 vim_free(save); 3804 vim_free(save);
3768 } 3805 }
3769 else 3806 else
3770 changed_bytes((linenr_T)n, 0); 3807 changed_bytes((linenr_T)n, 0);
3771 3808
3772 restore_buffer(savebuf); 3809 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
3773 3810
3774 /* Check that the cursor is not beyond the end of the line now. */ 3811 /* Check that the cursor is not beyond the end of the line now. */
3775 if (buf == savebuf) 3812 if (buf == curbuf)
3776 check_cursor_col(); 3813 check_cursor_col();
3777 3814
3778 if (VimTryEnd()) 3815 if (VimTryEnd())
3779 return FAIL; 3816 return FAIL;
3780 3817
3804 PyInt lo, 3841 PyInt lo,
3805 PyInt hi, 3842 PyInt hi,
3806 PyObject *list, 3843 PyObject *list,
3807 PyInt *len_change) 3844 PyInt *len_change)
3808 { 3845 {
3846 buf_T *save_curbuf = NULL;
3847 win_T *save_curwin = NULL;
3848 tabpage_T *save_curtab = NULL;
3849
3809 /* First of all, we check the type of the supplied Python object. 3850 /* First of all, we check the type of the supplied Python object.
3810 * There are three cases: 3851 * There are three cases:
3811 * 1. NULL, or None - this is a deletion. 3852 * 1. NULL, or None - this is a deletion.
3812 * 2. A list - this is a replacement. 3853 * 2. A list - this is a replacement.
3813 * 3. Anything else - this is an error. 3854 * 3. Anything else - this is an error.
3814 */ 3855 */
3815 if (list == Py_None || list == NULL) 3856 if (list == Py_None || list == NULL)
3816 { 3857 {
3817 PyInt i; 3858 PyInt i;
3818 PyInt n = (int)(hi - lo); 3859 PyInt n = (int)(hi - lo);
3819 buf_T *savebuf;
3820 3860
3821 PyErr_Clear(); 3861 PyErr_Clear();
3822 VimTryStart(); 3862 VimTryStart();
3823 switch_buffer(&savebuf, buf); 3863 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
3824 3864
3825 if (u_savedel((linenr_T)lo, (long)n) == FAIL) 3865 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
3826 RAISE_UNDO_FAIL; 3866 RAISE_UNDO_FAIL;
3827 else 3867 else
3828 { 3868 {
3832 { 3872 {
3833 RAISE_DELETE_LINE_FAIL; 3873 RAISE_DELETE_LINE_FAIL;
3834 break; 3874 break;
3835 } 3875 }
3836 } 3876 }
3837 if (buf == savebuf) 3877 if (buf == curbuf)
3838 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n); 3878 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
3839 deleted_lines_mark((linenr_T)lo, (long)i); 3879 if (save_curbuf == NULL)
3840 } 3880 /* Only adjust marks if we managed to switch to a window that
3841 3881 * holds the buffer, otherwise line numbers will be invalid. */
3842 restore_buffer(savebuf); 3882 deleted_lines_mark((linenr_T)lo, (long)i);
3883 }
3884
3885 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
3843 3886
3844 if (VimTryEnd()) 3887 if (VimTryEnd())
3845 return FAIL; 3888 return FAIL;
3846 3889
3847 if (len_change) 3890 if (len_change)
3854 PyInt i; 3897 PyInt i;
3855 PyInt new_len = PyList_Size(list); 3898 PyInt new_len = PyList_Size(list);
3856 PyInt old_len = hi - lo; 3899 PyInt old_len = hi - lo;
3857 PyInt extra = 0; /* lines added to text, can be negative */ 3900 PyInt extra = 0; /* lines added to text, can be negative */
3858 char **array; 3901 char **array;
3859 buf_T *savebuf;
3860 3902
3861 if (new_len == 0) /* avoid allocating zero bytes */ 3903 if (new_len == 0) /* avoid allocating zero bytes */
3862 array = NULL; 3904 array = NULL;
3863 else 3905 else
3864 { 3906 {
3886 3928
3887 VimTryStart(); 3929 VimTryStart();
3888 PyErr_Clear(); 3930 PyErr_Clear();
3889 3931
3890 /* START of region without "return". Must call restore_buffer()! */ 3932 /* START of region without "return". Must call restore_buffer()! */
3891 switch_buffer(&savebuf, buf); 3933 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
3892 3934
3893 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL) 3935 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
3894 RAISE_UNDO_FAIL; 3936 RAISE_UNDO_FAIL;
3895 3937
3896 /* If the size of the range is reducing (ie, new_len < old_len) we 3938 /* If the size of the range is reducing (ie, new_len < old_len) we
3958 */ 4000 */
3959 PyMem_Free(array); 4001 PyMem_Free(array);
3960 4002
3961 /* Adjust marks. Invalidate any which lie in the 4003 /* Adjust marks. Invalidate any which lie in the
3962 * changed range, and move any in the remainder of the buffer. 4004 * changed range, and move any in the remainder of the buffer.
3963 */ 4005 * Only adjust marks if we managed to switch to a window that holds
3964 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1), 4006 * the buffer, otherwise line numbers will be invalid. */
4007 if (save_curbuf == NULL)
4008 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
3965 (long)MAXLNUM, (long)extra); 4009 (long)MAXLNUM, (long)extra);
3966 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra); 4010 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
3967 4011
3968 if (buf == savebuf) 4012 if (buf == curbuf)
3969 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra); 4013 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
3970 4014
3971 /* END of region without "return". */ 4015 /* END of region without "return". */
3972 restore_buffer(savebuf); 4016 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
3973 4017
3974 if (VimTryEnd()) 4018 if (VimTryEnd())
3975 return FAIL; 4019 return FAIL;
3976 4020
3977 if (len_change) 4021 if (len_change)
3996 */ 4040 */
3997 static int 4041 static int
3998 InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change) 4042 InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
3999 { 4043 {
4000 buf_T *save_curbuf = NULL; 4044 buf_T *save_curbuf = NULL;
4001 win_T *wp;
4002 win_T *save_curwin = NULL; 4045 win_T *save_curwin = NULL;
4003 tabpage_T *tp;
4004 tabpage_T *save_curtab = NULL; 4046 tabpage_T *save_curtab = NULL;
4005 4047
4006 /* First of all, we check the type of the supplied Python object. 4048 /* First of all, we check the type of the supplied Python object.
4007 * It must be a string or a list, or the call is in error. 4049 * It must be a string or a list, or the call is in error.
4008 */ 4050 */
4013 if (str == NULL) 4055 if (str == NULL)
4014 return FAIL; 4056 return FAIL;
4015 4057
4016 PyErr_Clear(); 4058 PyErr_Clear();
4017 VimTryStart(); 4059 VimTryStart();
4018 if (find_win_for_buf(buf, &wp, &tp) == FAIL 4060 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4019 || switch_win(&save_curwin, &save_curtab, wp, tp, TRUE)
4020 == FAIL)
4021 switch_buffer(&save_curbuf, buf);
4022 4061
4023 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL) 4062 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
4024 RAISE_UNDO_FAIL; 4063 RAISE_UNDO_FAIL;
4025 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL) 4064 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
4026 RAISE_INSERT_LINE_FAIL; 4065 RAISE_INSERT_LINE_FAIL;
4028 /* Only adjust marks if we managed to switch to a window that 4067 /* Only adjust marks if we managed to switch to a window that
4029 * holds the buffer, otherwise line numbers will be invalid. */ 4068 * holds the buffer, otherwise line numbers will be invalid. */
4030 appended_lines_mark((linenr_T)n, 1L); 4069 appended_lines_mark((linenr_T)n, 1L);
4031 4070
4032 vim_free(str); 4071 vim_free(str);
4033 if (save_curbuf == NULL) 4072 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
4034 restore_win(save_curwin, save_curtab, TRUE);
4035 else
4036 restore_buffer(save_curbuf);
4037 update_screen(VALID); 4073 update_screen(VALID);
4038 4074
4039 if (VimTryEnd()) 4075 if (VimTryEnd())
4040 return FAIL; 4076 return FAIL;
4041 4077
4071 } 4107 }
4072 } 4108 }
4073 4109
4074 PyErr_Clear(); 4110 PyErr_Clear();
4075 VimTryStart(); 4111 VimTryStart();
4076 if (find_win_for_buf(buf, &wp, &tp) == FAIL 4112 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4077 || switch_win(&save_curwin, &save_curtab, wp, tp, TRUE)
4078 == FAIL)
4079 switch_buffer(&save_curbuf, buf);
4080 4113
4081 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL) 4114 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
4082 RAISE_UNDO_FAIL; 4115 RAISE_UNDO_FAIL;
4083 else 4116 else
4084 { 4117 {
4095 4128
4096 break; 4129 break;
4097 } 4130 }
4098 vim_free(array[i]); 4131 vim_free(array[i]);
4099 } 4132 }
4100 if (i > 0) 4133 if (i > 0 && save_curbuf == NULL)
4134 /* Only adjust marks if we managed to switch to a window that
4135 * holds the buffer, otherwise line numbers will be invalid. */
4101 appended_lines_mark((linenr_T)n, (long)i); 4136 appended_lines_mark((linenr_T)n, (long)i);
4102 } 4137 }
4103 4138
4104 /* Free the array of lines. All of its contents have now 4139 /* Free the array of lines. All of its contents have now
4105 * been freed. */ 4140 * been freed. */
4106 PyMem_Free(array); 4141 PyMem_Free(array);
4107 4142 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
4108 if (save_curbuf == NULL) 4143
4109 restore_win(save_curwin, save_curtab, TRUE);
4110 else
4111 restore_buffer(save_curbuf);
4112 update_screen(VALID); 4144 update_screen(VALID);
4113 4145
4114 if (VimTryEnd()) 4146 if (VimTryEnd())
4115 return FAIL; 4147 return FAIL;
4116 4148