Mercurial > vim
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 |