To: vim_dev@googlegroups.com Subject: Patch 8.0.1815 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1815 (after 8.0.1814) Problem: Still a crash with terminal window and with 'lazyredraw' set. (Antoine) Solution: Do not wipe out the buffer when updating the screen. Files: src/terminal.c, src/proto/terminal.pro, src/screen.c, src/proto/screen.pro, src/ui.c *** ../vim-8.0.1814/src/terminal.c 2018-05-11 20:48:24.803810853 +0200 --- src/terminal.c 2018-05-11 21:49:00.634487103 +0200 *************** *** 103,108 **** --- 103,110 ---- int tl_normal_mode; /* TRUE: Terminal-Normal mode */ int tl_channel_closed; + int tl_channel_recently_closed; // still need to handle tl_finish + int tl_finish; #define TL_FINISH_UNSET NUL #define TL_FINISH_CLOSE 'c' /* ++close or :terminal without argument */ *************** *** 2780,2785 **** --- 2782,2834 ---- }; /* + * Do the work after the channel of a terminal was closed. + * Must be called only when updating_screen is FALSE. + * Returns TRUE when a buffer was closed (list of terminals may have changed). + */ + static int + term_after_channel_closed(term_T *term) + { + /* Unless in Terminal-Normal mode: clear the vterm. */ + if (!term->tl_normal_mode) + { + int fnum = term->tl_buffer->b_fnum; + + cleanup_vterm(term); + + if (term->tl_finish == TL_FINISH_CLOSE) + { + aco_save_T aco; + + /* ++close or term_finish == "close" */ + ch_log(NULL, "terminal job finished, closing window"); + aucmd_prepbuf(&aco, term->tl_buffer); + do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE); + aucmd_restbuf(&aco); + return TRUE; + } + if (term->tl_finish == TL_FINISH_OPEN + && term->tl_buffer->b_nwindows == 0) + { + char buf[50]; + + /* TODO: use term_opencmd */ + ch_log(NULL, "terminal job finished, opening window"); + vim_snprintf(buf, sizeof(buf), + term->tl_opencmd == NULL + ? "botright sbuf %d" + : (char *)term->tl_opencmd, fnum); + do_cmdline_cmd((char_u *)buf); + } + else + ch_log(NULL, "terminal job finished"); + } + + redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); + return FALSE; + } + + /* * Called when a channel has been closed. * If this was a channel for a terminal window then finish it up. */ *************** *** 2787,2795 **** term_channel_closed(channel_T *ch) { term_T *term; int did_one = FALSE; ! for (term = first_term; term != NULL; term = term->tl_next) if (term->tl_job == ch->ch_job) { term->tl_channel_closed = TRUE; --- 2836,2847 ---- term_channel_closed(channel_T *ch) { term_T *term; + term_T *next_term; int did_one = FALSE; ! for (term = first_term; term != NULL; term = next_term) ! { ! next_term = term->tl_next; if (term->tl_job == ch->ch_job) { term->tl_channel_closed = TRUE; *************** *** 2805,2847 **** } #endif ! /* Unless in Terminal-Normal mode: clear the vterm. */ ! if (!term->tl_normal_mode) { ! int fnum = term->tl_buffer->b_fnum; ! ! cleanup_vterm(term); ! ! if (term->tl_finish == TL_FINISH_CLOSE) ! { ! aco_save_T aco; ! ! /* ++close or term_finish == "close" */ ! ch_log(NULL, "terminal job finished, closing window"); ! aucmd_prepbuf(&aco, term->tl_buffer); ! do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE); ! aucmd_restbuf(&aco); ! break; ! } ! if (term->tl_finish == TL_FINISH_OPEN ! && term->tl_buffer->b_nwindows == 0) ! { ! char buf[50]; ! ! /* TODO: use term_opencmd */ ! ch_log(NULL, "terminal job finished, opening window"); ! vim_snprintf(buf, sizeof(buf), ! term->tl_opencmd == NULL ! ? "botright sbuf %d" ! : (char *)term->tl_opencmd, fnum); ! do_cmdline_cmd((char_u *)buf); ! } ! else ! ch_log(NULL, "terminal job finished"); } ! redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); } if (did_one) { redraw_statuslines(); --- 2857,2875 ---- } #endif ! if (updating_screen) { ! /* Cannot open or close windows now. Can happen when ! * 'lazyredraw' is set. */ ! term->tl_channel_recently_closed = TRUE; ! continue; } ! if (term_after_channel_closed(term)) ! next_term = first_term; } + } + if (did_one) { redraw_statuslines(); *************** *** 2859,2864 **** --- 2887,2915 ---- } } } + + /* + * To be called after resetting updating_screen: handle any terminal where the + * channel was closed. + */ + void + term_check_channel_closed_recently() + { + term_T *term; + term_T *next_term; + + for (term = first_term; term != NULL; term = next_term) + { + next_term = term->tl_next; + if (term->tl_channel_recently_closed) + { + term->tl_channel_recently_closed = FALSE; + if (term_after_channel_closed(term)) + // start over, the list may have changed + next_term = first_term; + } + } + } /* * Fill one screen line from a line of the terminal. *** ../vim-8.0.1814/src/proto/terminal.pro 2018-05-10 18:05:52.541048471 +0200 --- src/proto/terminal.pro 2018-05-11 21:49:05.006461139 +0200 *************** *** 20,25 **** --- 20,26 ---- int terminal_loop(int blocking); void term_job_ended(job_T *job); void term_channel_closed(channel_T *ch); + void term_check_channel_closed_recently(void); int term_do_update_window(win_T *wp); void term_update_window(win_T *wp); int term_is_finished(buf_T *buf); *** ../vim-8.0.1814/src/screen.c 2018-05-10 15:09:45.893646659 +0200 --- src/screen.c 2018-05-11 21:59:36.538421642 +0200 *************** *** 514,519 **** --- 514,532 ---- #endif } + void + reset_updating_screen(int may_resize_shell UNUSED) + { + updating_screen = FALSE; + #ifdef FEAT_GUI + if (may_resize_shell) + gui_may_resize_shell(); + #endif + #ifdef FEAT_TERMINAL + term_check_channel_closed_recently(); + #endif + } + /* * Update all windows that are editing the current buffer. */ *************** *** 778,787 **** FOR_ALL_WINDOWS(wp) wp->w_buffer->b_mod_set = FALSE; ! updating_screen = FALSE; ! #ifdef FEAT_GUI ! gui_may_resize_shell(); ! #endif /* Clear or redraw the command line. Done last, because scrolling may * mess up the command line. */ --- 791,797 ---- FOR_ALL_WINDOWS(wp) wp->w_buffer->b_mod_set = FALSE; ! reset_updating_screen(TRUE); /* Clear or redraw the command line. Done last, because scrolling may * mess up the command line. */ *************** *** 861,871 **** end_search_hl(); # endif ! updating_screen = FALSE; # ifdef FEAT_GUI - gui_may_resize_shell(); - /* Redraw the cursor and update the scrollbars when all screen updating is * done. */ if (gui.in_use) --- 871,879 ---- end_search_hl(); # endif ! reset_updating_screen(TRUE); # ifdef FEAT_GUI /* Redraw the cursor and update the scrollbars when all screen updating is * done. */ if (gui.in_use) *** ../vim-8.0.1814/src/proto/screen.pro 2018-05-10 15:09:45.893646659 +0200 --- src/proto/screen.pro 2018-05-11 21:59:39.766397331 +0200 *************** *** 9,14 **** --- 9,15 ---- int redraw_asap(int type); void redraw_after_callback(int call_update_screen); void redrawWinline(linenr_T lnum, int invalid); + void reset_updating_screen(int may_resize_shell); void update_curbuf(int type); int update_screen(int type_arg); int conceal_cursor_line(win_T *wp); *** ../vim-8.0.1814/src/ui.c 2018-05-10 15:09:45.893646659 +0200 --- src/ui.c 2018-05-11 21:58:49.282780697 +0200 *************** *** 415,421 **** #endif mch_breakcheck(force); ! updating_screen = save_us; } /***************************************************************************** --- 415,424 ---- #endif mch_breakcheck(force); ! if (save_us) ! updating_screen = save_us; ! else ! reset_updating_screen(FALSE); } /***************************************************************************** *** ../vim-8.0.1814/src/version.c 2018-05-11 20:48:24.803810853 +0200 --- src/version.c 2018-05-11 22:00:25.210057829 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1815, /**/ -- TIM: But follow only if you are men of valour. For the entrance to this cave is guarded by a monster, a creature so foul and cruel that no man yet has fought with it and lived. Bones of full fifty men lie strewn about its lair ... "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@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 ///