To: vim_dev@googlegroups.com Subject: Patch 8.2.4018 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4018 Problem: ml_get error when win_execute redraws with Visual selection. Solution: Disable Visual area temporarily. (closes #9479) Files: src/evalwindow.c, src/proto/evalwindow.pro, src/structs.h, src/evalbuffer.c, src/proto/evalbuffer.pro, src/evalvars.c, src/if_py_both.h, src/evalfunc.c, src/testdir/test_execute_func.vim *** ../vim-8.2.4017/src/evalwindow.c 2022-01-01 16:20:56.900401501 +0000 --- src/evalwindow.c 2022-01-06 13:15:18.345263077 +0000 *************** *** 689,696 **** int id; tabpage_T *tp; win_T *wp; ! win_T *save_curwin; ! tabpage_T *save_curtab; // Return an empty string if something fails. rettv->v_type = VAR_STRING; --- 689,695 ---- int id; tabpage_T *tp; win_T *wp; ! switchwin_T switchwin; // Return an empty string if something fails. rettv->v_type = VAR_STRING; *************** *** 727,738 **** } #endif ! if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, TRUE) == OK) { check_cursor(); execute_common(argvars, rettv, 1); } ! restore_win_noblock(save_curwin, save_curtab, TRUE); #ifdef FEAT_AUTOCHDIR if (apply_acd) do_autochdir(); --- 726,737 ---- } #endif ! if (switch_win_noblock(&switchwin, wp, tp, TRUE) == OK) { check_cursor(); execute_common(argvars, rettv, 1); } ! restore_win_noblock(&switchwin, TRUE); #ifdef FEAT_AUTOCHDIR if (apply_acd) do_autochdir(); *************** *** 1247,1260 **** */ int switch_win( ! win_T **save_curwin, ! tabpage_T **save_curtab, ! win_T *win, ! tabpage_T *tp, ! int no_display) { block_autocmds(); ! return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display); } /* --- 1246,1258 ---- */ int switch_win( ! switchwin_T *switchwin, ! win_T *win, ! tabpage_T *tp, ! int no_display) { block_autocmds(); ! return switch_win_noblock(switchwin, win, tp, no_display); } /* *************** *** 1262,1277 **** */ int switch_win_noblock( ! win_T **save_curwin, ! tabpage_T **save_curtab, ! win_T *win, ! tabpage_T *tp, ! int no_display) ! { ! *save_curwin = curwin; if (tp != NULL) { ! *save_curtab = curtab; if (no_display) { curtab->tp_firstwin = firstwin; --- 1260,1284 ---- */ int switch_win_noblock( ! switchwin_T *switchwin, ! win_T *win, ! tabpage_T *tp, ! int no_display) ! { ! CLEAR_POINTER(switchwin); ! switchwin->sw_curwin = curwin; ! if (win == curwin) ! switchwin->sw_same_win = TRUE; ! else ! { ! // Disable Visual selection, because redrawing may fail. ! switchwin->sw_visual_active = VIsual_active; ! VIsual_active = FALSE; ! } ! if (tp != NULL) { ! switchwin->sw_curtab = curtab; if (no_display) { curtab->tp_firstwin = firstwin; *************** *** 1299,1309 **** */ void restore_win( ! win_T *save_curwin, ! tabpage_T *save_curtab, ! int no_display) { ! restore_win_noblock(save_curwin, save_curtab, no_display); unblock_autocmds(); } --- 1306,1315 ---- */ void restore_win( ! switchwin_T *switchwin, ! int no_display) { ! restore_win_noblock(switchwin, no_display); unblock_autocmds(); } *************** *** 1312,1339 **** */ void restore_win_noblock( ! win_T *save_curwin, ! tabpage_T *save_curtab, ! int no_display) { ! if (save_curtab != NULL && valid_tabpage(save_curtab)) { if (no_display) { curtab->tp_firstwin = firstwin; curtab->tp_lastwin = lastwin; curtab->tp_topframe = topframe; ! curtab = save_curtab; firstwin = curtab->tp_firstwin; lastwin = curtab->tp_lastwin; topframe = curtab->tp_topframe; } else ! goto_tabpage_tp(save_curtab, FALSE, FALSE); } ! if (win_valid(save_curwin)) { ! curwin = save_curwin; curbuf = curwin->w_buffer; } # ifdef FEAT_PROP_POPUP --- 1318,1348 ---- */ void restore_win_noblock( ! switchwin_T *switchwin, ! int no_display) { ! if (switchwin->sw_curtab != NULL && valid_tabpage(switchwin->sw_curtab)) { if (no_display) { curtab->tp_firstwin = firstwin; curtab->tp_lastwin = lastwin; curtab->tp_topframe = topframe; ! curtab = switchwin->sw_curtab; firstwin = curtab->tp_firstwin; lastwin = curtab->tp_lastwin; topframe = curtab->tp_topframe; } else ! goto_tabpage_tp(switchwin->sw_curtab, FALSE, FALSE); } ! ! if (!switchwin->sw_same_win) ! VIsual_active = switchwin->sw_visual_active; ! ! if (win_valid(switchwin->sw_curwin)) { ! curwin = switchwin->sw_curwin; curbuf = curwin->w_buffer; } # ifdef FEAT_PROP_POPUP *** ../vim-8.2.4017/src/proto/evalwindow.pro 2020-02-14 13:32:15.966616351 +0000 --- src/proto/evalwindow.pro 2022-01-06 12:59:50.879303170 +0000 *************** *** 32,39 **** void f_winrestview(typval_T *argvars, typval_T *rettv); void f_winsaveview(typval_T *argvars, typval_T *rettv); void f_winwidth(typval_T *argvars, typval_T *rettv); ! int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display); ! int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display); ! void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display); ! void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab, int no_display); /* vim: set ft=c : */ --- 32,39 ---- void f_winrestview(typval_T *argvars, typval_T *rettv); void f_winsaveview(typval_T *argvars, typval_T *rettv); void f_winwidth(typval_T *argvars, typval_T *rettv); ! int switch_win(switchwin_T *switchwin, win_T *win, tabpage_T *tp, int no_display); ! int switch_win_noblock(switchwin_T *switchwin, win_T *win, tabpage_T *tp, int no_display); ! void restore_win(switchwin_T *switchwin, int no_display); ! void restore_win_noblock(switchwin_T *switchwin, int no_display); /* vim: set ft=c : */ *** ../vim-8.2.4017/src/structs.h 2022-01-04 15:54:34.592486131 +0000 --- src/structs.h 2022-01-06 12:55:59.807998284 +0000 *************** *** 4507,4509 **** --- 4507,4516 ---- FILTERMAP_MAPNEW } filtermap_T; + // Structure used by switch_win() to pass values to restore_win() + typedef struct { + win_T *sw_curwin; + tabpage_T *sw_curtab; + int sw_same_win; // VIsual_active was not reset + int sw_visual_active; + } switchwin_T; *** ../vim-8.2.4017/src/evalbuffer.c 2022-01-04 15:16:57.879864882 +0000 --- src/evalbuffer.c 2022-01-06 13:02:27.514849722 +0000 *************** *** 930,960 **** */ void switch_to_win_for_buf( ! buf_T *buf, ! win_T **save_curwinp, ! tabpage_T **save_curtabp, ! bufref_T *save_curbuf) { win_T *wp; tabpage_T *tp; if (find_win_for_buf(buf, &wp, &tp) == FAIL) switch_buffer(save_curbuf, buf); ! else if (switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL) { ! restore_win(*save_curwinp, *save_curtabp, TRUE); switch_buffer(save_curbuf, buf); } } void restore_win_for_buf( ! win_T *save_curwin, ! tabpage_T *save_curtab, ! bufref_T *save_curbuf) { if (save_curbuf->br_buf == NULL) ! restore_win(save_curwin, save_curtab, TRUE); else restore_buffer(save_curbuf); } --- 930,958 ---- */ void switch_to_win_for_buf( ! buf_T *buf, ! switchwin_T *switchwin, ! bufref_T *save_curbuf) { win_T *wp; tabpage_T *tp; if (find_win_for_buf(buf, &wp, &tp) == FAIL) switch_buffer(save_curbuf, buf); ! else if (switch_win(switchwin, wp, tp, TRUE) == FAIL) { ! restore_win(switchwin, TRUE); switch_buffer(save_curbuf, buf); } } void restore_win_for_buf( ! switchwin_T *switchwin, ! bufref_T *save_curbuf) { if (save_curbuf->br_buf == NULL) ! restore_win(switchwin, TRUE); else restore_buffer(save_curbuf); } *** ../vim-8.2.4017/src/proto/evalbuffer.pro 2022-01-04 15:16:57.883864877 +0000 --- src/proto/evalbuffer.pro 2022-01-06 13:14:41.121206694 +0000 *************** *** 21,26 **** void f_setline(typval_T *argvars, typval_T *rettv); void switch_buffer(bufref_T *save_curbuf, buf_T *buf); void restore_buffer(bufref_T *save_curbuf); ! void switch_to_win_for_buf(buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, bufref_T *save_curbuf); ! void restore_win_for_buf(win_T *save_curwin, tabpage_T *save_curtab, bufref_T *save_curbuf); /* vim: set ft=c : */ --- 21,26 ---- void f_setline(typval_T *argvars, typval_T *rettv); void switch_buffer(bufref_T *save_curbuf, buf_T *buf); void restore_buffer(bufref_T *save_curbuf); ! void switch_to_win_for_buf(buf_T *buf, switchwin_T *switchwin, bufref_T *save_curbuf); ! void restore_win_for_buf(switchwin_T *switchwin, bufref_T *save_curbuf); /* vim: set ft=c : */ *** ../vim-8.2.4017/src/evalvars.c 2022-01-05 20:24:34.272005652 +0000 --- src/evalvars.c 2022-01-06 13:06:45.626122855 +0000 *************** *** 3769,3776 **** dictitem_T *v; tabpage_T *tp = NULL; int done = FALSE; ! win_T *oldcurwin; ! tabpage_T *oldtabpage; int need_switch_win; if (off == 1) --- 3769,3775 ---- dictitem_T *v; tabpage_T *tp = NULL; int done = FALSE; ! switchwin_T switchwin; int need_switch_win; if (off == 1) *************** *** 3791,3797 **** // autocommands get blocked. need_switch_win = !(tp == curtab && win == curwin); if (!need_switch_win ! || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) { if (*varname == '&') { --- 3790,3796 ---- // autocommands get blocked. need_switch_win = !(tp == curtab && win == curwin); if (!need_switch_win ! || switch_win(&switchwin, win, tp, TRUE) == OK) { if (*varname == '&') { *************** *** 3826,3832 **** if (need_switch_win) // restore previous notion of curwin ! restore_win(oldcurwin, oldtabpage, TRUE); } if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) --- 3825,3831 ---- if (need_switch_win) // restore previous notion of curwin ! restore_win(&switchwin, TRUE); } if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) *************** *** 3869,3876 **** setwinvar(typval_T *argvars, int off) { win_T *win; ! win_T *save_curwin; ! tabpage_T *save_curtab; int need_switch_win; char_u *varname, *winvarname; typval_T *varp; --- 3868,3874 ---- setwinvar(typval_T *argvars, int off) { win_T *win; ! switchwin_T switchwin; int need_switch_win; char_u *varname, *winvarname; typval_T *varp; *************** *** 3891,3897 **** { need_switch_win = !(tp == curtab && win == curwin); if (!need_switch_win ! || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) { if (*varname == '&') set_option_from_tv(varname + 1, varp); --- 3889,3895 ---- { need_switch_win = !(tp == curtab && win == curwin); if (!need_switch_win ! || switch_win(&switchwin, win, tp, TRUE) == OK) { if (*varname == '&') set_option_from_tv(varname + 1, varp); *************** *** 3908,3914 **** } } if (need_switch_win) ! restore_win(save_curwin, save_curtab, TRUE); } } --- 3906,3912 ---- } } if (need_switch_win) ! restore_win(&switchwin, TRUE); } } *************** *** 4165,4172 **** void f_gettabvar(typval_T *argvars, typval_T *rettv) { ! win_T *oldcurwin; ! tabpage_T *tp, *oldtabpage; dictitem_T *v; char_u *varname; int done = FALSE; --- 4163,4170 ---- void f_gettabvar(typval_T *argvars, typval_T *rettv) { ! switchwin_T switchwin; ! tabpage_T *tp; dictitem_T *v; char_u *varname; int done = FALSE; *************** *** 4185,4191 **** { // Set tp to be our tabpage, temporarily. Also set the window to the // first window in the tabpage, otherwise the window is not valid. ! if (switch_win(&oldcurwin, &oldtabpage, tp == curtab || tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin, tp, TRUE) == OK) { --- 4183,4189 ---- { // Set tp to be our tabpage, temporarily. Also set the window to the // first window in the tabpage, otherwise the window is not valid. ! if (switch_win(&switchwin, tp == curtab || tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin, tp, TRUE) == OK) { *************** *** 4200,4206 **** } // restore previous notion of curwin ! restore_win(oldcurwin, oldtabpage, TRUE); } if (!done && argvars[2].v_type != VAR_UNKNOWN) --- 4198,4204 ---- } // restore previous notion of curwin ! restore_win(&switchwin, TRUE); } if (!done && argvars[2].v_type != VAR_UNKNOWN) *** ../vim-8.2.4017/src/if_py_both.h 2022-01-05 20:24:34.276005641 +0000 --- src/if_py_both.h 2022-01-06 13:23:43.385320550 +0000 *************** *** 3529,3536 **** int opt_type, void *from) { ! win_T *save_curwin = NULL; ! tabpage_T *save_curtab = NULL; bufref_T save_curbuf; int set_ret = 0; --- 3529,3535 ---- int opt_type, void *from) { ! switchwin_T switchwin; bufref_T save_curbuf; int set_ret = 0; *************** *** 3538,3554 **** switch (opt_type) { case SREQ_WIN: ! if (switch_win(&save_curwin, &save_curtab, (win_T *)from, win_find_tabpage((win_T *)from), FALSE) == FAIL) { ! restore_win(save_curwin, save_curtab, TRUE); if (VimTryEnd()) return -1; PyErr_SET_VIM(N_("problem while switching windows")); return -1; } set_ret = set_option_value_err(key, numval, stringval, opt_flags); ! restore_win(save_curwin, save_curtab, TRUE); break; case SREQ_BUF: switch_buffer(&save_curbuf, (buf_T *)from); --- 3537,3553 ---- switch (opt_type) { case SREQ_WIN: ! if (switch_win(&switchwin, (win_T *)from, win_find_tabpage((win_T *)from), FALSE) == FAIL) { ! restore_win(&switchwin, TRUE); if (VimTryEnd()) return -1; PyErr_SET_VIM(N_("problem while switching windows")); return -1; } set_ret = set_option_value_err(key, numval, stringval, opt_flags); ! restore_win(&switchwin, TRUE); break; case SREQ_BUF: switch_buffer(&save_curbuf, (buf_T *)from); *************** *** 4410,4417 **** SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change) { bufref_T save_curbuf = {NULL, 0, 0}; ! 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: --- 4409,4415 ---- SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change) { bufref_T save_curbuf = {NULL, 0, 0}; ! switchwin_T switchwin; // First of all, we check the type of the supplied Python object. // There are three cases: *************** *** 4421,4427 **** if (line == Py_None || line == NULL) { PyErr_Clear(); ! switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf); VimTryStart(); --- 4419,4426 ---- if (line == Py_None || line == NULL) { PyErr_Clear(); ! switchwin.sw_curwin = NULL; ! switch_to_win_for_buf(buf, &switchwin, &save_curbuf); VimTryStart(); *************** *** 4431,4437 **** RAISE_DELETE_LINE_FAIL; else { ! if (buf == curbuf && (save_curwin != NULL || save_curbuf.br_buf == NULL)) // Using an existing window for the buffer, adjust the cursor // position. --- 4430,4436 ---- RAISE_DELETE_LINE_FAIL; else { ! if (buf == curbuf && (switchwin.sw_curwin != NULL || save_curbuf.br_buf == NULL)) // Using an existing window for the buffer, adjust the cursor // position. *************** *** 4442,4448 **** deleted_lines_mark((linenr_T)n, 1L); } ! restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); if (VimTryEnd()) return FAIL; --- 4441,4447 ---- deleted_lines_mark((linenr_T)n, 1L); } ! restore_win_for_buf(&switchwin, &save_curbuf); if (VimTryEnd()) return FAIL; *************** *** 4463,4469 **** // 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) { --- 4462,4468 ---- // We do not need to free "save" if ml_replace() consumes it. PyErr_Clear(); ! switch_to_win_for_buf(buf, &switchwin, &save_curbuf); if (u_savesub((linenr_T)n) == FAIL) { *************** *** 4478,4484 **** 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) --- 4477,4483 ---- else changed_bytes((linenr_T)n, 0); ! restore_win_for_buf(&switchwin, &save_curbuf); // Check that the cursor is not beyond the end of the line now. if (buf == curbuf) *************** *** 4517,4524 **** PyInt *len_change) { bufref_T save_curbuf = {NULL, 0, 0}; ! 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: --- 4516,4522 ---- PyInt *len_change) { bufref_T save_curbuf = {NULL, 0, 0}; ! switchwin_T switchwin; // First of all, we check the type of the supplied Python object. // There are three cases: *************** *** 4532,4538 **** 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; --- 4530,4537 ---- PyErr_Clear(); VimTryStart(); ! switchwin.sw_curwin = NULL; ! switch_to_win_for_buf(buf, &switchwin, &save_curbuf); if (u_savedel((linenr_T)lo, (long)n) == FAIL) RAISE_UNDO_FAIL; *************** *** 4546,4552 **** break; } } ! if (buf == curbuf && (save_curwin != NULL || save_curbuf.br_buf == NULL)) // Using an existing window for the buffer, adjust the cursor // position. --- 4545,4551 ---- break; } } ! if (buf == curbuf && (switchwin.sw_curwin != NULL || save_curbuf.br_buf == NULL)) // Using an existing window for the buffer, adjust the cursor // position. *************** *** 4557,4563 **** deleted_lines_mark((linenr_T)lo, (long)i); } ! restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); if (VimTryEnd()) return FAIL; --- 4556,4562 ---- deleted_lines_mark((linenr_T)lo, (long)i); } ! restore_win_for_buf(&switchwin, &save_curbuf); if (VimTryEnd()) return FAIL; *************** *** 4605,4611 **** 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; --- 4604,4611 ---- PyErr_Clear(); // START of region without "return". Must call restore_buffer()! ! switchwin.sw_curwin = NULL; ! switch_to_win_for_buf(buf, &switchwin, &save_curbuf); if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL) RAISE_UNDO_FAIL; *************** *** 4680,4693 **** (long)MAXLNUM, (long)extra); changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra); ! if (buf == curbuf && (save_curwin != NULL || save_curbuf.br_buf == NULL)) // Using an existing window for the buffer, adjust the cursor // position. 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; --- 4680,4693 ---- (long)MAXLNUM, (long)extra); changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra); ! if (buf == curbuf && (switchwin.sw_curwin != NULL || save_curbuf.br_buf == NULL)) // Using an existing window for the buffer, adjust the cursor // position. py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra); // END of region without "return". ! restore_win_for_buf(&switchwin, &save_curbuf); if (VimTryEnd()) return FAIL; *************** *** 4717,4724 **** InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change) { bufref_T save_curbuf = {NULL, 0, 0}; ! win_T *save_curwin = NULL; ! 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. --- 4717,4723 ---- InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change) { bufref_T save_curbuf = {NULL, 0, 0}; ! switchwin_T switchwin; // 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. *************** *** 4731,4737 **** 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; --- 4730,4736 ---- PyErr_Clear(); VimTryStart(); ! switch_to_win_for_buf(buf, &switchwin, &save_curbuf); if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL) RAISE_UNDO_FAIL; *************** *** 4743,4749 **** 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()) --- 4742,4748 ---- appended_lines_mark((linenr_T)n, 1L); vim_free(str); ! restore_win_for_buf(&switchwin, &save_curbuf); update_screen(VALID); if (VimTryEnd()) *************** *** 4783,4789 **** 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; --- 4782,4788 ---- PyErr_Clear(); VimTryStart(); ! switch_to_win_for_buf(buf, &switchwin, &save_curbuf); if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL) RAISE_UNDO_FAIL; *************** *** 4813,4819 **** // 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); --- 4812,4818 ---- // Free the array of lines. All of its contents have now // been freed. PyMem_Free(array); ! restore_win_for_buf(&switchwin, &save_curbuf); update_screen(VALID); *** ../vim-8.2.4017/src/evalfunc.c 2022-01-05 20:24:34.272005652 +0000 --- src/evalfunc.c 2022-01-06 13:05:44.858292129 +0000 *************** *** 6864,6871 **** int id; tabpage_T *tp; win_T *wp; ! win_T *save_curwin; ! tabpage_T *save_curtab; if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL --- 6864,6870 ---- int id; tabpage_T *tp; win_T *wp; ! switchwin_T switchwin; if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL *************** *** 6879,6891 **** wp = win_id2wp_tp(id, &tp); if (wp != NULL && tp != NULL) { ! if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, TRUE) ! == OK) { check_cursor(); fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE); } ! restore_win_noblock(save_curwin, save_curtab, TRUE); } } else --- 6878,6889 ---- wp = win_id2wp_tp(id, &tp); if (wp != NULL && tp != NULL) { ! if (switch_win_noblock(&switchwin, wp, tp, TRUE) == OK) { check_cursor(); fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE); } ! restore_win_noblock(&switchwin, TRUE); } } else *** ../vim-8.2.4017/src/testdir/test_execute_func.vim 2021-12-20 21:35:55.314175835 +0000 --- src/testdir/test_execute_func.vim 2022-01-06 12:46:37.045944846 +0000 *************** *** 149,154 **** --- 149,164 ---- unlet xyz endfunc + func Test_win_execute_visual_redraw() + call setline(1, ['a', 'b', 'c']) + new + wincmd p + call feedkeys("G\", 'txn') + call win_execute(winnr('#')->win_getid(), 'redraw') + bwipe! + bwipe! + endfunc + func Test_win_execute_on_startup() CheckRunVimInTerminal *** ../vim-8.2.4017/src/version.c 2022-01-06 12:35:27.984532089 +0000 --- src/version.c 2022-01-06 13:24:09.985298304 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4018, /**/ -- You can tune a file system, but you can't tuna fish -- man tunefs /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///