diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-09-19 23:06:20 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-09-19 23:06:20 +0200 |
commit | 7528d1f6b5422750eb778dfb550cfd0b0e540964 (patch) | |
tree | 4282e05be0cf40c3e1920bdb4f2b5abe88e820ff /src/screen.c | |
parent | cd67059c0c3abf1e28aa66458abdf6f338252eb2 (diff) |
patch 8.1.2057: the screen.c file is much too bigv8.1.2057
Problem: The screen.c file is much too big.
Solution: Split it in three parts. (Yegappan Lakshmanan, closes #4943)
Diffstat (limited to 'src/screen.c')
-rw-r--r-- | src/screen.c | 6511 |
1 files changed, 59 insertions, 6452 deletions
diff --git a/src/screen.c b/src/screen.c index 4d976fd686..0120d11eb3 100644 --- a/src/screen.c +++ b/src/screen.c @@ -8,7 +8,7 @@ */ /* - * screen.c: code for displaying on the screen + * screen.c: Lower level code for displaying on the screen. * * Output to the screen (console, terminal emulator or GUI window) is minimized * by remembering what is already on the screen, and only updating the parts @@ -35,110 +35,15 @@ * * The screen_*() functions write to the screen and handle updating * ScreenLines[]. - * - * update_screen() is the function that updates all windows and status lines. - * It is called form the main loop when must_redraw is non-zero. It may be - * called from other places when an immediate screen update is needed. - * - * The part of the buffer that is displayed in a window is set with: - * - w_topline (first buffer line in window) - * - w_topfill (filler lines above the first line) - * - w_leftcol (leftmost window cell in window), - * - w_skipcol (skipped window cells of first line) - * - * Commands that only move the cursor around in a window, do not need to take - * action to update the display. The main loop will check if w_topline is - * valid and update it (scroll the window) when needed. - * - * Commands that scroll a window change w_topline and must call - * check_cursor() to move the cursor into the visible part of the window, and - * call redraw_later(VALID) to have the window displayed by update_screen() - * later. - * - * Commands that change text in the buffer must call changed_bytes() or - * changed_lines() to mark the area that changed and will require updating - * later. The main loop will call update_screen(), which will update each - * window that shows the changed buffer. This assumes text above the change - * can remain displayed as it is. Text after the change may need updating for - * scrolling, folding and syntax highlighting. - * - * Commands that change how a window is displayed (e.g., setting 'list') or - * invalidate the contents of a window in another way (e.g., change fold - * settings), must call redraw_later(NOT_VALID) to have the whole window - * redisplayed by update_screen() later. - * - * Commands that change how a buffer is displayed (e.g., setting 'tabstop') - * must call redraw_curbuf_later(NOT_VALID) to have all the windows for the - * buffer redisplayed by update_screen() later. - * - * Commands that change highlighting and possibly cause a scroll too must call - * redraw_later(SOME_VALID) to update the whole window but still use scrolling - * to avoid redrawing everything. But the length of displayed lines must not - * change, use NOT_VALID then. - * - * Commands that move the window position must call redraw_later(NOT_VALID). - * TODO: should minimize redrawing by scrolling when possible. - * - * Commands that change everything (e.g., resizing the screen) must call - * redraw_all_later(NOT_VALID) or redraw_all_later(CLEAR). - * - * Things that are handled indirectly: - * - When messages scroll the screen up, msg_scrolled will be set and - * update_screen() called to redraw. */ #include "vim.h" -#define MB_FILLER_CHAR '<' /* character used when a double-width character - * doesn't fit. */ - /* * The attributes that are actually active for writing to the screen. */ static int screen_attr = 0; -/* - * Positioning the cursor is reduced by remembering the last position. - * Mostly used by windgoto() and screen_char(). - */ -static int screen_cur_row, screen_cur_col; /* last known cursor position */ - -#ifdef FEAT_SEARCH_EXTRA -static match_T search_hl; // used for 'hlsearch' highlight matching -#endif - -#ifdef FEAT_FOLDING -static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ -static int compute_foldcolumn(win_T *wp, int col); -#endif - -/* Flag that is set when drawing for a callback, not from the main command - * loop. */ -static int redrawing_for_callback = 0; - -/* - * Buffer for one screen line (characters and attributes). - */ -static schar_T *current_ScreenLine; - -static void win_update(win_T *wp); -static void win_redr_status(win_T *wp, int ignore_pum); -static void win_draw_end(win_T *wp, int c1, int c2, int draw_margin, int row, int endrow, hlf_T hl); -#ifdef FEAT_FOLDING -static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row); -static void fill_foldcolumn(char_u *p, win_T *wp, int closed, linenr_T lnum); -static void copy_text_attr(int off, char_u *buf, int len, int attr); -#endif -static int win_line(win_T *, linenr_T, int, int, int nochange, int number_only); -static void draw_vsep_win(win_T *wp, int row); -#ifdef FEAT_STL_OPT -static void redraw_custom_statusline(win_T *wp); -#endif -#ifdef FEAT_SEARCH_EXTRA -static void start_search_hl(void); -static void end_search_hl(void); -#endif -static void screen_char(unsigned off, int row, int col); static void screen_char_2(unsigned off, int row, int col); static void screenclear2(void); static void lineclear(unsigned off, int width, int attr); @@ -147,762 +52,10 @@ static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int de static void win_rest_invalid(win_T *wp); static void msg_pos_mode(void); static void recording_mode(int attr); -static int fillchar_status(int *attr, win_T *wp); -static int fillchar_vsep(int *attr); -#ifdef FEAT_MENU -static void redraw_win_toolbar(win_T *wp); -#endif -#ifdef FEAT_STL_OPT -static void win_redr_custom(win_T *wp, int draw_ruler); -#endif -#ifdef FEAT_CMDL_INFO -static void win_redr_ruler(win_T *wp, int always, int ignore_pum); -#endif -#ifdef FEAT_SYN_HL -static void margin_columns_win(win_T *wp, int *left_col, int *right_col); -#endif /* Ugly global: overrule attribute used by screen_char() */ static int screen_char_attr = 0; -#ifdef FEAT_RIGHTLEFT -# define HAS_RIGHTLEFT(x) x -#else -# define HAS_RIGHTLEFT(x) FALSE -#endif - -// flags for screen_line() -#define SLF_RIGHTLEFT 1 -#define SLF_POPUP 2 - -/* - * Redraw the current window later, with update_screen(type). - * Set must_redraw only if not already set to a higher value. - * E.g. if must_redraw is CLEAR, type NOT_VALID will do nothing. - */ - void -redraw_later(int type) -{ - redraw_win_later(curwin, type); -} - - void -redraw_win_later( - win_T *wp, - int type) -{ - if (!exiting && wp->w_redr_type < type) - { - wp->w_redr_type = type; - if (type >= NOT_VALID) - wp->w_lines_valid = 0; - if (must_redraw < type) /* must_redraw is the maximum of all windows */ - must_redraw = type; - } -} - -/* - * Force a complete redraw later. Also resets the highlighting. To be used - * after executing a shell command that messes up the screen. - */ - void -redraw_later_clear(void) -{ - redraw_all_later(CLEAR); -#ifdef FEAT_GUI - if (gui.in_use) - /* Use a code that will reset gui.highlight_mask in - * gui_stop_highlight(). */ - screen_attr = HL_ALL + 1; - else -#endif - /* Use attributes that is very unlikely to appear in text. */ - screen_attr = HL_BOLD | HL_UNDERLINE | HL_INVERSE | HL_STRIKETHROUGH; -} - -/* - * Mark all windows to be redrawn later. - */ - void -redraw_all_later(int type) -{ - win_T *wp; - - FOR_ALL_WINDOWS(wp) - redraw_win_later(wp, type); - // This may be needed when switching tabs. - if (must_redraw < type) - must_redraw = type; -} - -/* - * Mark all windows that are editing the current buffer to be updated later. - */ - void -redraw_curbuf_later(int type) -{ - redraw_buf_later(curbuf, type); -} - - void -redraw_buf_later(buf_T *buf, int type) -{ - win_T *wp; - - FOR_ALL_WINDOWS(wp) - { - if (wp->w_buffer == buf) - redraw_win_later(wp, type); - } -} - -#if defined(FEAT_SIGNS) || defined(PROTO) - void -redraw_buf_line_later(buf_T *buf, linenr_T lnum) -{ - win_T *wp; - - FOR_ALL_WINDOWS(wp) - if (wp->w_buffer == buf && lnum >= wp->w_topline - && lnum < wp->w_botline) - redrawWinline(wp, lnum); -} -#endif - -#if defined(FEAT_JOB_CHANNEL) || defined(PROTO) - void -redraw_buf_and_status_later(buf_T *buf, int type) -{ - win_T *wp; - -#ifdef FEAT_WILDMENU - if (wild_menu_showing != 0) - /* Don't redraw while the command line completion is displayed, it - * would disappear. */ - return; -#endif - FOR_ALL_WINDOWS(wp) - { - if (wp->w_buffer == buf) - { - redraw_win_later(wp, type); - wp->w_redr_status = TRUE; - } - } -} -#endif - -#if defined(FEAT_TERMRESPONSE) || defined(PROTO) -/* - * Redraw as soon as possible. When the command line is not scrolled redraw - * right away and restore what was on the command line. - * Return a code indicating what happened. - */ - int -redraw_asap(int type) -{ - int rows; - int cols = screen_Columns; - int r; - int ret = 0; - schar_T *screenline; /* copy from ScreenLines[] */ - sattr_T *screenattr; /* copy from ScreenAttrs[] */ - int i; - u8char_T *screenlineUC = NULL; /* copy from ScreenLinesUC[] */ - u8char_T *screenlineC[MAX_MCO]; /* copy from ScreenLinesC[][] */ - schar_T *screenline2 = NULL; /* copy from ScreenLines2[] */ - - redraw_later(type); - if (msg_scrolled || (State != NORMAL && State != NORMAL_BUSY) || exiting) - return ret; - - /* Allocate space to save the text displayed in the command line area. */ - rows = screen_Rows - cmdline_row; - screenline = LALLOC_MULT(schar_T, rows * cols); - screenattr = LALLOC_MULT(sattr_T, rows * cols); - if (screenline == NULL || screenattr == NULL) - ret = 2; - if (enc_utf8) - { - screenlineUC = LALLOC_MULT(u8char_T, rows * cols); - if (screenlineUC == NULL) - ret = 2; - for (i = 0; i < p_mco; ++i) - { - screenlineC[i] = LALLOC_MULT(u8char_T, rows * cols); - if (screenlineC[i] == NULL) - ret = 2; - } - } - if (enc_dbcs == DBCS_JPNU) - { - screenline2 = LALLOC_MULT(schar_T, rows * cols); - if (screenline2 == NULL) - ret = 2; - } - - if (ret != 2) - { - /* Save the text displayed in the command line area. */ - for (r = 0; r < rows; ++r) - { - mch_memmove(screenline + r * cols, - ScreenLines + LineOffset[cmdline_row + r], - (size_t)cols * sizeof(schar_T)); - mch_memmove(screenattr + r * cols, - ScreenAttrs + LineOffset[cmdline_row + r], - (size_t)cols * sizeof(sattr_T)); - if (enc_utf8) - { - mch_memmove(screenlineUC + r * cols, - ScreenLinesUC + LineOffset[cmdline_row + r], - (size_t)cols * sizeof(u8char_T)); - for (i = 0; i < p_mco; ++i) - mch_memmove(screenlineC[i] + r * cols, - ScreenLinesC[i] + LineOffset[cmdline_row + r], - (size_t)cols * sizeof(u8char_T)); - } - if (enc_dbcs == DBCS_JPNU) - mch_memmove(screenline2 + r * cols, - ScreenLines2 + LineOffset[cmdline_row + r], - (size_t)cols * sizeof(schar_T)); - } - - update_screen(0); - ret = 3; - - if (must_redraw == 0) - { - int off = (int)(current_ScreenLine - ScreenLines); - - /* Restore the text displayed in the command line area. */ - for (r = 0; r < rows; ++r) - { - mch_memmove(current_ScreenLine, - screenline + r * cols, - (size_t)cols * sizeof(schar_T)); - mch_memmove(ScreenAttrs + off, - screenattr + r * cols, - (size_t)cols * sizeof(sattr_T)); - if (enc_utf8) - { - mch_memmove(ScreenLinesUC + off, - screenlineUC + r * cols, - (size_t)cols * sizeof(u8char_T)); - for (i = 0; i < p_mco; ++i) - mch_memmove(ScreenLinesC[i] + off, - screenlineC[i] + r * cols, - (size_t)cols * sizeof(u8char_T)); - } - if (enc_dbcs == DBCS_JPNU) - mch_memmove(ScreenLines2 + off, - screenline2 + r * cols, - (size_t)cols * sizeof(schar_T)); - screen_line(cmdline_row + r, 0, cols, cols, 0); - } - ret = 4; - } - } - - vim_free(screenline); - vim_free(screenattr); - if (enc_utf8) - { - vim_free(screenlineUC); - for (i = 0; i < p_mco; ++i) - vim_free(screenlineC[i]); - } - if (enc_dbcs == DBCS_JPNU) - vim_free(screenline2); - - /* Show the intro message when appropriate. */ - maybe_intro_message(); - - setcursor(); - - return ret; -} -#endif - -/* - * Invoked after an asynchronous callback is called. - * If an echo command was used the cursor needs to be put back where - * it belongs. If highlighting was changed a redraw is needed. - * If "call_update_screen" is FALSE don't call update_screen() when at the - * command line. - */ - void -redraw_after_callback(int call_update_screen) -{ - ++redrawing_for_callback; - - if (State == HITRETURN || State == ASKMORE) - ; // do nothing - else if (State & CMDLINE) - { - // Don't redraw when in prompt_for_number(). - if (cmdline_row > 0) - { - // Redrawing only works when the screen didn't scroll. Don't clear - // wildmenu entries. - if (msg_scrolled == 0 -#ifdef FEAT_WILDMENU - && wild_menu_showing == 0 -#endif - && call_update_screen) - update_screen(0); - - // Redraw in the same position, so that the user can continue - // editing the command. - redrawcmdline_ex(FALSE); - } - } - else if (State & (NORMAL | INSERT | TERMINAL)) - { - // keep the command line if possible - update_screen(VALID_NO_UPDATE); - setcursor(); - } - cursor_on(); -#ifdef FEAT_GUI - if (gui.in_use && !gui_mch_is_blink_off()) - // Don't update the cursor when it is blinking and off to avoid - // flicker. - out_flush_cursor(FALSE, FALSE); - else -#endif - out_flush(); - - --redrawing_for_callback; -} - -/* - * Changed something in the current window, at buffer line "lnum", that - * requires that line and possibly other lines to be redrawn. - * Used when entering/leaving Insert mode with the cursor on a folded line. - * Used to remove the "$" from a change command. - * Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot - * may become invalid and the whole window will have to be redrawn. - */ - void -redrawWinline( - win_T *wp, - linenr_T lnum) -{ - if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) - wp->w_redraw_top = lnum; - if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) - wp->w_redraw_bot = lnum; - redraw_win_later(wp, VALID); -} - -/* - * To be called when "updating_screen" was set before and now the postponed - * side effects may take place. - */ - void -after_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 - -#ifdef HAVE_DROP_FILE - // If handle_drop() was called while updating_screen was TRUE need to - // handle the drop now. - handle_any_postponed_drop(); -#endif -} - -/* - * Update all windows that are editing the current buffer. - */ - void -update_curbuf(int type) -{ - redraw_curbuf_later(type); - update_screen(type); -} - -/* - * Based on the current value of curwin->w_topline, transfer a screenfull - * of stuff from Filemem to ScreenLines[], and update curwin->w_botline. - * Return OK when the screen was updated, FAIL if it was not done. - */ - int -update_screen(int type_arg) -{ - int type = type_arg; - win_T *wp; - static int did_intro = FALSE; -#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) - int did_one; -#endif -#ifdef FEAT_GUI - int did_undraw = FALSE; - int gui_cursor_col = 0; - int gui_cursor_row = 0; -#endif - int no_update = FALSE; - - /* Don't do anything if the screen structures are (not yet) valid. */ - if (!screen_valid(TRUE)) - return FAIL; - - if (type == VALID_NO_UPDATE) - { - no_update = TRUE; - type = 0; - } - -#ifdef FEAT_EVAL - { - buf_T *buf; - - // Before updating the screen, notify any listeners of changed text. - FOR_ALL_BUFFERS(buf) - invoke_listeners(buf); - } -#endif - -#ifdef FEAT_DIFF - // May have postponed updating diffs. - if (need_diff_redraw) - diff_redraw(TRUE); -#endif - - if (must_redraw) - { - if (type < must_redraw) /* use maximal type */ - type = must_redraw; - - /* must_redraw is reset here, so that when we run into some weird - * reason to redraw while busy redrawing (e.g., asynchronous - * scrolling), or update_topline() in win_update() will cause a - * scroll, the screen will be redrawn later or in win_update(). */ - must_redraw = 0; - } - - /* May need to update w_lines[]. */ - if (curwin->w_lines_valid == 0 && type < NOT_VALID -#ifdef FEAT_TERMINAL - && !term_do_update_window(curwin) -#endif - ) - type = NOT_VALID; - - /* Postpone the redrawing when it's not needed and when being called - * recursively. */ - if (!redrawing() || updating_screen) - { - redraw_later(type); /* remember type for next time */ - must_redraw = type; - if (type > INVERTED_ALL) - curwin->w_lines_valid = 0; /* don't use w_lines[].wl_size now */ - return FAIL; - } - updating_screen = TRUE; - -#ifdef FEAT_TEXT_PROP - // Update popup_mask if needed. This may set w_redraw_top and w_redraw_bot - // in some windows. - may_update_popup_mask(type); -#endif - -#ifdef FEAT_SYN_HL - ++display_tick; /* let syntax code know we're in a next round of - * display updating */ -#endif - if (no_update) - ++no_win_do_lines_ins; - - /* - * if the screen was scrolled up when displaying a message, scroll it down - */ - if (msg_scrolled) - { - clear_cmdline = TRUE; - if (msg_scrolled > Rows - 5) /* clearing is faster */ - type = CLEAR; - else if (type != CLEAR) - { - check_for_delay(FALSE); - if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, 0, NULL) - == FAIL) - type = CLEAR; - FOR_ALL_WINDOWS(wp) - { - if (wp->w_winrow < msg_scrolled) - { - if (W_WINROW(wp) + wp->w_height > msg_scrolled - && wp->w_redr_type < REDRAW_TOP - && wp->w_lines_valid > 0 - && wp->w_topline == wp->w_lines[0].wl_lnum) - { - wp->w_upd_rows = msg_scrolled - W_WINROW(wp); - wp->w_redr_type = REDRAW_TOP; - } - else - { - wp->w_redr_type = NOT_VALID; - if (W_WINROW(wp) + wp->w_height + wp->w_status_height - <= msg_scrolled) - wp->w_redr_status = TRUE; - } - } - } - if (!no_update) - redraw_cmdline = TRUE; - redraw_tabline = TRUE; - } - msg_scrolled = 0; - need_wait_return = FALSE; - } - - /* reset cmdline_row now (may have been changed temporarily) */ - compute_cmdrow(); - - /* Check for changed highlighting */ - if (need_highlight_changed) - highlight_changed(); - - if (type == CLEAR) /* first clear screen */ - { - screenclear(); /* will reset clear_cmdline */ - type = NOT_VALID; - /* must_redraw may be set indirectly, avoid another redraw later */ - must_redraw = 0; - } - - if (clear_cmdline) /* going to clear cmdline (done below) */ - check_for_delay(FALSE); - -#ifdef FEAT_LINEBREAK - /* Force redraw when width of 'number' or 'relativenumber' column - * changes. */ - if (curwin->w_redr_type < NOT_VALID - && curwin->w_nrwidth != ((curwin->w_p_nu || curwin->w_p_rnu) - ? number_width(curwin) : 0)) - curwin->w_redr_type = NOT_VALID; -#endif - - /* - * Only start redrawing if there is really something to do. - */ - if (type == INVERTED) - update_curswant(); - if (curwin->w_redr_type < type - && !((type == VALID - && curwin->w_lines[0].wl_valid -#ifdef FEAT_DIFF - && curwin->w_topfill == curwin->w_old_topfill - && curwin->w_botfill == curwin->w_old_botfill -#endif - && curwin->w_topline == curwin->w_lines[0].wl_lnum) - || (type == INVERTED - && VIsual_active - && curwin->w_old_cursor_lnum == curwin->w_cursor.lnum - && curwin->w_old_visual_mode == VIsual_mode - && (curwin->w_valid & VALID_VIRTCOL) - && curwin->w_old_curswant == curwin->w_curswant) - )) - curwin->w_redr_type = type; - - /* Redraw the tab pages line if needed. */ - if (redraw_tabline || type >= NOT_VALID) - draw_tabline(); - -#ifdef FEAT_SYN_HL - /* - * Correct stored syntax highlighting info for changes in each displayed - * buffer. Each buffer must only be done once. - */ - FOR_ALL_WINDOWS(wp) - { - if (wp->w_buffer->b_mod_set) - { - win_T *wwp; - - /* Check if we already did this buffer. */ - for (wwp = firstwin; wwp != wp; wwp = wwp->w_next) - if (wwp->w_buffer == wp->w_buffer) - break; - if (wwp == wp && syntax_present(wp)) - syn_stack_apply_changes(wp->w_buffer); - } - } -#endif - - /* - * Go from top to bottom through the windows, redrawing the ones that need - * it. - */ -#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) - did_one = FALSE; -#endif -#ifdef FEAT_SEARCH_EXTRA - search_hl.rm.regprog = NULL; -#endif - FOR_ALL_WINDOWS(wp) - { - if (wp->w_redr_type != 0) - { - cursor_off(); -#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) - if (!did_one) - { - did_one = TRUE; -# ifdef FEAT_SEARCH_EXTRA - start_search_hl(); -# endif -# ifdef FEAT_CLIPBOARD - /* When Visual area changed, may have to update selection. */ - if (clip_star.available && clip_isautosel_star()) - clip_update_selection(&clip_star); - if (clip_plus.available && clip_isautosel_plus()) - clip_update_selection(&clip_plus); -# endif -#ifdef FEAT_GUI - /* Remove the cursor before starting to do anything, because - * scrolling may make it difficult to redraw the text under - * it. */ - if (gui.in_use && wp == curwin) - { - gui_cursor_col = gui.cursor_col; - gui_cursor_row = gui.cursor_row; - gui_undraw_cursor(); - did_undraw = TRUE; - } -#endif - } -#endif - win_update(wp); - } - - /* redraw status line after the window to minimize cursor movement */ - if (wp->w_redr_status) - { - cursor_off(); - win_redr_status(wp, TRUE); // any popup menu will be redrawn below - } - } -#if defined(FEAT_SEARCH_EXTRA) - end_search_hl(); -#endif - /* May need to redraw the popup menu. */ - pum_may_redraw(); - - /* Reset b_mod_set flags. Going through all windows is probably faster - * than going through all buffers (there could be many buffers). */ - FOR_ALL_WINDOWS(wp) - wp->w_buffer->b_mod_set = FALSE; - -#ifdef FEAT_TEXT_PROP - // Display popup windows on top of the windows and command line. - update_popups(win_update); -#endif - - after_updating_screen(TRUE); - - /* Clear or redraw the command line. Done last, because scrolling may - * mess up the command line. */ - if (clear_cmdline || redraw_cmdline || redraw_mode) - showmode(); - - if (no_update) - --no_win_do_lines_ins; - - /* May put up an introductory message when not editing a file */ - if (!did_intro) - maybe_intro_message(); - did_intro = TRUE; - -#ifdef FEAT_GUI - /* Redraw the cursor and update the scrollbars when all screen updating is - * done. */ - if (gui.in_use) - { - if (did_undraw && !gui_mch_is_blink_off()) - { - mch_disable_flush(); - out_flush(); /* required before updating the cursor */ - mch_enable_flush(); - - /* Put the GUI position where the cursor was, gui_update_cursor() - * uses that. */ - gui.col = gui_cursor_col; - gui.row = gui_cursor_row; - gui.col = mb_fix_col(gui.col, gui.row); - gui_update_cursor(FALSE, FALSE); - gui_may_flush(); - screen_cur_col = gui.col; - screen_cur_row = gui.row; - } - else - out_flush(); - gui_update_scrollbars(FALSE); - } -#endif - return OK; -} - -#if defined(FEAT_NETBEANS_INTG) || defined(FEAT_GUI) -/* - * Prepare for updating one or more windows. - * Caller must check for "updating_screen" already set to avoid recursiveness. - */ - static void -update_prepare(void) -{ - cursor_off(); - updating_screen = TRUE; -#ifdef FEAT_GUI - /* Remove the cursor before starting to do anything, because scrolling may - * make it difficult to redraw the text under it. */ - if (gui.in_use) - gui_undraw_cursor(); -#endif -#ifdef FEAT_SEARCH_EXTRA - start_search_hl(); -#endif -#ifdef FEAT_TEXT_PROP - // Update popup_mask if needed. - may_update_popup_mask(must_redraw); -#endif -} - -/* - * Finish updating one or more windows. - */ - static void -update_finish(void) -{ - if (redraw_cmdline || redraw_mode) - showmode(); - -# ifdef FEAT_SEARCH_EXTRA - end_search_hl(); -# endif - - after_updating_screen(TRUE); - -# ifdef FEAT_GUI - /* Redraw the cursor and update the scrollbars when all screen updating is - * done. */ - if (gui.in_use) - { - out_flush_cursor(FALSE, FALSE); - gui_update_scrollbars(FALSE); - } -# endif -} -#endif - #if defined(FEAT_CONCEAL) || defined(PROTO) /* * Return TRUE if the cursor line in window "wp" may be concealed, according @@ -944,52 +97,6 @@ conceal_check_cursor_line(void) } #endif -#if defined(FEAT_NETBEANS_INTG) || defined(PROTO) - void -update_debug_sign(buf_T *buf, linenr_T lnum) -{ - win_T *wp; - int doit = FALSE; - -# ifdef FEAT_FOLDING - win_foldinfo.fi_level = 0; -# endif - - // update/delete a specific sign - redraw_buf_line_later(buf, lnum); - - // check if it resulted in the need to redraw a window - FOR_ALL_WINDOWS(wp) - if (wp->w_redr_type != 0) - doit = TRUE; - - /* Return when there is nothing to do, screen updating is already - * happening (recursive call), messages on the screen or still starting up. - */ - if (!doit || updating_screen - || State == ASKMORE || State == HITRETURN - || msg_scrolled -#ifdef FEAT_GUI - || gui.starting -#endif - || starting) - return; - - /* update all windows that need updating */ - update_prepare(); - - FOR_ALL_WINDOWS(wp) - { - if (wp->w_redr_type != 0) - win_update(wp); - if (wp->w_redr_status) - win_redr_status(wp, FALSE); - } - - update_finish(); -} -#endif - /* * Get 'wincolor' attribute for window "wp". If not set and "wp" is a popup * window then get the "Pmenu" highlight attribute. @@ -1013,1353 +120,6 @@ get_wcr_attr(win_T *wp) return wcr_attr; } -#if defined(FEAT_GUI) || defined(PROTO) -/* - * Update a single window, its status line and maybe the command line msg. - * Used for the GUI scrollbar. - */ - void -updateWindow(win_T *wp) -{ - /* return if already busy updating */ - if (updating_screen) - return; - - update_prepare(); - -#ifdef FEAT_CLIPBOARD - /* When Visual area changed, may have to update selection. */ - if (clip_star.available && clip_isautosel_star()) - clip_update_selection(&clip_star); - if (clip_plus.available && clip_isautosel_plus()) - clip_update_selection(&clip_plus); -#endif - - win_update(wp); - - /* When the screen was cleared redraw the tab pages line. */ - if (redraw_tabline) - draw_tabline(); - - if (wp->w_redr_status -# ifdef FEAT_CMDL_INFO - || p_ru -# endif -# ifdef FEAT_STL_OPT - || *p_stl != NUL || *wp->w_p_stl != NUL -# endif - ) - win_redr_status(wp, FALSE); - -#ifdef FEAT_TEXT_PROP - // Display popup windows on top of everything. - update_popups(win_update); -#endif - - update_finish(); -} -#endif - -/* - * Update a single window. - * - * This may cause the windows below it also to be redrawn (when clearing the - * screen or scrolling lines). - * - * How the window is redrawn depends on wp->w_redr_type. Each type also - * implies the one below it. - * NOT_VALID redraw the whole window - * SOME_VALID redraw the whole window but do scroll when possible - * REDRAW_TOP redraw the top w_upd_rows window lines, otherwise like VALID - * INVERTED redraw the changed part of the Visual area - * INVERTED_ALL redraw the whole Visual area - * VALID 1. scroll up/down to adjust for a changed w_topline - * 2. update lines at the top when scrolled down - * 3. redraw changed text: - * - if wp->w_buffer->b_mod_set set, update lines between - * b_mod_top and b_mod_bot. - * - if wp->w_redraw_top non-zero, redraw lines between - * wp->w_redraw_top and wp->w_redr_bot. - * - continue redrawing when syntax status is invalid. - * 4. if scrolled up, update lines at the bottom. - * This results in three areas that may need updating: - * top: from first row to top_end (when scrolled down) - * mid: from mid_start to mid_end (update inversion or changed text) - * bot: from bot_start to last row (when scrolled up) - */ - static void -win_update(win_T *wp) -{ - buf_T *buf = wp->w_buffer; - int type; - int top_end = 0; /* Below last row of the top area that needs - updating. 0 when no top area updating. */ - int mid_start = 999;/* first row of the mid area that needs - updating. 999 when no mid area updating. */ - int mid_end = 0; /* Below last row of the mid area that needs - updating. 0 when no mid area updating. */ - int bot_start = 999;/* first row of the bot area that needs - updating. 999 when no bot area updating */ - int scrolled_down = FALSE; /* TRUE when scrolled down when - w_topline got smaller a bit */ -#ifdef FEAT_SEARCH_EXTRA - int top_to_mod = FALSE; // redraw above mod_top -#endif - - int row; /* current window row to display */ - linenr_T lnum; /* current buffer lnum to display */ - int idx; /* current index in w_lines[] */ - int srow; /* starting row of the current line */ - - int eof = FALSE; /* if TRUE, we hit the end of the file */ - int didline = FALSE; /* if TRUE, we finished the last line */ - int i; - long j; - static int recursive = FALSE; /* being called recursively */ - int old_botline = wp->w_botline; -#ifdef FEAT_FOLDING - long fold_count; -#endif -#ifdef FEAT_SYN_HL - /* remember what happened to the previous line, to know if - * check_visual_highlight() can be used */ -#define DID_NONE 1 /* didn't update a line */ -#define DID_LINE 2 /* updated a normal line */ -#define DID_FOLD 3 /* updated a folded line */ - int did_update = DID_NONE; - linenr_T syntax_last_parsed = 0; /* last parsed text line */ -#endif - linenr_T mod_top = 0; - linenr_T mod_bot = 0; -#if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) - int save_got_int; -#endif -#ifdef SYN_TIME_LIMIT - proftime_T syntax_tm; -#endif - - type = wp->w_redr_type; - - if (type == NOT_VALID) - { - wp->w_redr_status = TRUE; - wp->w_lines_valid = 0; - } - - /* Window is zero-height: nothing to draw. */ - if (wp->w_height + WINBAR_HEIGHT(wp) == 0) - { - wp->w_redr_type = 0; - return; - } - - /* Window is zero-width: Only need to draw the separator. */ - if (wp->w_width == 0) - { - /* draw the vertical separator right of this window */ - draw_vsep_win(wp, 0); - wp->w_redr_type = 0; - return; - } - -#ifdef FEAT_TERMINAL - // If this window contains a terminal, redraw works completely differently. - if (term_do_update_window(wp)) - { - term_update_window(wp); -# ifdef FEAT_MENU - /* Draw the window toolbar, if there is one. */ - if (winbar_height(wp) > 0) - redraw_win_toolbar(wp); -# endif - wp->w_redr_type = 0; - return; - } -#endif - -#ifdef FEAT_SEARCH_EXTRA - init_search_hl(wp, &search_hl); -#endif - -#ifdef FEAT_LINEBREAK - /* Force redraw when width of 'number' or 'relativenumber' column - * changes. */ - i = (wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) : 0; - if (wp->w_nrwidth != i) - { - type = NOT_VALID; - wp->w_nrwidth = i; - } - else -#endif - - if (buf->b_mod_set && buf->b_mod_xlines != 0 && wp->w_redraw_top != 0) - { - /* - * When there are both inserted/deleted lines and specific lines to be - * redrawn, w_redraw_top and w_redraw_bot may be invalid, just redraw - * everything (only happens when redrawing is off for while). - */ - type = NOT_VALID; - } - else - { - /* - * Set mod_top to the first line that needs displaying because of - * changes. Set mod_bot to the first line after the changes. - */ - mod_top = wp->w_redraw_top; - if (wp->w_redraw_bot != 0) - mod_bot = wp->w_redraw_bot + 1; - else - mod_bot = 0; - if (buf->b_mod_set) - { - if (mod_top == 0 || mod_top > buf->b_mod_top) - { - mod_top = buf->b_mod_top; -#ifdef FEAT_SYN_HL - /* Need to redraw lines above the change that may be included - * in a pattern match. */ - if (syntax_present(wp)) - { - mod_top -= buf->b_s.b_syn_sync_linebreaks; - if (mod_top < 1) - mod_ |