/* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * screen.c: 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 * that changed. * * ScreenLines[off] Contains a copy of the whole screen, as it is currently * displayed (excluding text written by external commands). * ScreenAttrs[off] Contains the associated attributes. * LineOffset[row] Contains the offset into ScreenLines*[] and ScreenAttrs[] * for each line. * LineWraps[row] Flag for each line whether it wraps to the next line. * * For double-byte characters, two consecutive bytes in ScreenLines[] can form * one character which occupies two display cells. * For UTF-8 a multi-byte character is converted to Unicode and stored in * ScreenLinesUC[]. ScreenLines[] contains the first byte only. For an ASCII * character without composing chars ScreenLinesUC[] will be 0. When the * character occupies two display cells the next byte in ScreenLines[] is 0. * ScreenLinesC[][] contain up to 'maxcombine' composing characters * (drawn on top of the first character). They are 0 when not used. * ScreenLines2[] is only used for euc-jp to store the second byte if the * first byte is 0x8e (single-width character). * * 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 line 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" /* * 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/* * Struct used for highlighting 'hlsearch' matches for the last use search * pattern or a ":match" item. * For 'hlsearch' there is one pattern for all windows. For ":match" there is * a different pattern for each window. */typedef struct{ regmmatch_T rm; /* points to the regexp program; contains last found match (may continue in next line) */ buf_T *buf; /* the buffer to search for a match */ linenr_T lnum; /* the line to search for a match */ int attr; /* attributes to be used for a match */ int attr_cur; /* attributes currently active in win_line() */ linenr_T first_lnum; /* first lnum to search for multi-line pat */ colnr_T startcol; /* in win_line() points to char where HL starts */ colnr_T endcol; /* in win_line() points to char where HL ends */} match_T; static match_T search_hl; /* used for 'hlsearch' highlight matching */static match_T match_hl[3]; /* used for ":match" highlight matching */#endif #ifdef FEAT_FOLDINGstatic foldinfo_T win_foldinfo; /* info for 'foldcolumn' */#endif /* * Buffer for one screen line (characters and attributes). */static schar_T *current_ScreenLine; static void win_update __ARGS((win_T *wp));static void win_draw_end __ARGS((win_T *wp, int c1, int c2, int row, int endrow, hlf_T hl));#ifdef FEAT_FOLDINGstatic void fold_line __ARGS((win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row));static void fill_foldcolumn __ARGS((char_u *p, win_T *wp, int closed, linenr_T lnum));static void copy_text_attr __ARGS((int off, char_u *buf, int len, int attr));#endifstatic int win_line __ARGS((win_T *, linenr_T, int, int, int nochange));static int char_needs_redraw __ARGS((int off_from, int off_to, int cols));#ifdef FEAT_RIGHTLEFTstatic void screen_line __ARGS((int row, int coloff, int endcol, int clear_width, int rlflag));# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))#elsestatic void screen_line __ARGS((int row, int coloff, int endcol, int clear_width));# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c))#endif#ifdef FEAT_VERTSPLITstatic void draw_vsep_win __ARGS((win_T *wp, int row));#endif#ifdef FEAT_STL_OPTstatic void redraw_custum_statusline __ARGS((win_T *wp));#endif#ifdef FEAT_SEARCH_EXTRAstatic void start_search_hl __ARGS((void));static void end_search_hl __ARGS((void));static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));static void next_search_hl __ARGS((win_T *win, match_T *shl, linenr_T lnum, colnr_T mincol));#endifstatic void screen_start_highlight __ARGS((int attr));static void screen_char __ARGS((unsigned off, int row, int col));#ifdef FEAT_MBYTEstatic void screen_char_2 __ARGS((unsigned off, int row, int col));#endifstatic void screenclear2 __ARGS((void));static void lineclear __ARGS((unsigned off, int width));static void lineinvalid __ARGS((unsigned off, int width));#ifdef FEAT_VERTSPLITstatic void linecopy __ARGS((int to, int from, win_T *wp));static void redraw_block __ARGS((int row, int end, win_T *wp));#endifstatic int win_do_lines __ARGS((win_T *wp, int row, int line_count, int mayclear, int del));static void win_rest_invalid __ARGS((win_T *wp));static void msg_pos_mode __ARGS((void));#if defined(FEAT_WINDOWS)static void draw_tabline __ARGS((void));#endif#if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT)static int fillchar_status __ARGS((int *attr, int is_curwin));#endif#ifdef FEAT_VERTSPLITstatic int fillchar_vsep __ARGS((int *attr));#endif#ifdef FEAT_STL_OPTstatic void win_redr_custom __ARGS((win_T *wp, int draw_ruler));#endif#ifdef FEAT_CMDL_INFOstatic void win_redr_ruler __ARGS((win_T *wp, int always));#endif #if defined(FEAT_CLIPBOARD) || defined(FEAT_VERTSPLIT)/* Ugly global: overrule attribute used by screen_char() */static int screen_char_attr = 0;#endif /* * 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. */ voidredraw_later(type) int type;{ redraw_win_later(curwin, type);} voidredraw_win_later(wp, type) win_T *wp; int type;{ if (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. */ voidredraw_later_clear(){ 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;} /* * Mark all windows to be redrawn later. */ voidredraw_all_later(type) int type;{ win_T *wp; FOR_ALL_WINDOWS(wp) { redraw_win_later(wp, type); }} /* * Mark all windows that are editing the current buffer to be updated later. */ voidredraw_curbuf_later(type) int type;{ redraw_buf_later(curbuf, type);} voidredraw_buf_later(buf, type) buf_T *buf; int type;{ win_T *wp; FOR_ALL_WINDOWS(wp) { if (wp->w_buffer == buf) redraw_win_later(wp, type); }} /* * 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. *//*ARGSUSED*/ voidredrawWinline(lnum, invalid) linenr_T lnum; int invalid; /* window line height is invalid now */{#ifdef FEAT_FOLDING int i;#endif if (curwin->w_redraw_top == 0 || curwin->w_redraw_top > lnum) curwin->w_redraw_top = lnum; if (curwin->w_redraw_bot == 0 || curwin->w_redraw_bot < lnum) curwin->w_redraw_bot = lnum; redraw_later(VALID); #ifdef FEAT_FOLDING if (invalid) { /* A w_lines[] entry for this lnum has become invalid. */ i = find_wl_entry(curwin, lnum); if (i >= 0) curwin->w_lines[i].wl_valid = FALSE; }#endif} /* * update all windows that are editing the current buffer */ voidupdate_curbuf(type) int type;{ redraw_curbuf_later(type); update_screen(type);} /* * update_screen() * * Based on the current value of curwin->w_topline, transfer a screenfull * of stuff from Filemem to ScreenLines[], and update curwin->w_botline. */ voidupdate_screen(type) int type;{ win_T *wp; static int did_intro = FALSE;#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) int did_one;#endif if (!screen_valid(TRUE)) return; if (must_redraw) { if (type < must_redraw) /* use maximal type */ type = must_redraw; must_redraw = 0; } /* Need to update w_lines[]. */ if (curwin->w_lines_valid == 0 && type < NOT_VALID) type = NOT_VALID; if (!redrawing()) { 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; } updating_screen = TRUE;#ifdef FEAT_SYN_HL ++display_tick; /* let syntax code know we're in a next round of * display updating */#endif /* * 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, NULL) == FAIL) type = CLEAR; FOR_ALL_WINDOWS(wp) { if (W_WINROW(wp) < 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;#ifdef FEAT_WINDOWS if (W_WINROW(wp) + wp->w_height + W_STATUS_HEIGHT(wp) <= msg_scrolled) wp->w_redr_status = TRUE;#endif } } } redraw_cmdline = TRUE;#ifdef FEAT_WINDOWS redraw_tabline = TRUE;#endif } 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; } if (clear_cmdline) /* going to clear cmdline (done below) */ check_for_delay(FALSE); #ifdef FEAT_LINEBREAK /* Force redraw when width of 'number' column changes. */ if (curwin->w_redr_type < NOT_VALID && curwin->w_nrwidth != (curwin->w_p_nu ? 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)#ifdef FEAT_VISUAL || (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)#endif )) curwin->w_redr_type = type; #ifdef FEAT_WINDOWS /* Redraw the tab pages line if needed. */ if (redraw_tabline || type >= NOT_VALID) draw_tabline();#endif #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) {# ifdef FEAT_WINDOWS 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;# endif if (# ifdef FEAT_WINDOWS wwp == wp &&# endif syntax_present(wp->w_buffer)) syn_stack_apply_changes(wp->w_buffer); } }#endif /*Lines 1–500 of 9417. Load more
/* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * screen.c: 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 * that changed. * * ScreenLines[off] Contains a copy of the whole screen, as it is currently * displayed (excluding text written by external commands). * ScreenAttrs[off] Contains the associated attributes. * LineOffset[row] Contains the offset into ScreenLines*[] and ScreenAttrs[] * for each line. * LineWraps[row] Flag for each line whether it wraps to the next line. * * For double-byte characters, two consecutive bytes in ScreenLines[] can form * one character which occupies two display cells. * For UTF-8 a multi-byte character is converted to Unicode and stored in * ScreenLinesUC[]. ScreenLines[] contains the first byte only. For an ASCII * character without composing chars ScreenLinesUC[] will be 0. When the * character occupies two display cells the next byte in ScreenLines[] is 0. * ScreenLinesC[][] contain up to 'maxcombine' composing characters * (drawn on top of the first character). They are 0 when not used. * ScreenLines2[] is only used for euc-jp to store the second byte if the * first byte is 0x8e (single-width character). * * 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 line 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" /* * 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 /* * Struct used for highlighting 'hlsearch' matches for the last use search * pattern or a ":match" item. * For 'hlsearch' there is one pattern for all windows. For ":match" there is * a different pattern for each window. */ typedef struct { regmmatch_T rm; /* points to the regexp program; contains last found match (may continue in next line) */ buf_T *buf; /* the buffer to search for a match */ linenr_T lnum; /* the line to search for a match */ int attr; /* attributes to be used for a match */ int attr_cur; /* attributes currently active in win_line() */ linenr_T first_lnum; /* first lnum to search for multi-line pat */ colnr_T startcol; /* in win_line() points to char where HL starts */ colnr_T endcol; /* in win_line() points to char where HL ends */ } match_T; static match_T search_hl; /* used for 'hlsearch' highlight matching */ static match_T match_hl[3]; /* used for ":match" highlight matching */ #endif #ifdef FEAT_FOLDING static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ #endif /* * Buffer for one screen line (characters and attributes). */ static schar_T *current_ScreenLine; static void win_update __ARGS((win_T *wp)); static void win_draw_end __ARGS((win_T *wp, int c1, int c2, int row, int endrow, hlf_T hl)); #ifdef FEAT_FOLDING static void fold_line __ARGS((win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row)); static void fill_foldcolumn __ARGS((char_u *p, win_T *wp, int closed, linenr_T lnum)); static void copy_text_attr __ARGS((int off, char_u *buf, int len, int attr)); #endif static int win_line __ARGS((win_T *, linenr_T, int, int, int nochange)); static int char_needs_redraw __ARGS((int off_from, int off_to, int cols)); #ifdef FEAT_RIGHTLEFT static void screen_line __ARGS((int row, int coloff, int endcol, int clear_width, int rlflag)); # define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl)) #else static void screen_line __ARGS((int row, int coloff, int endcol, int clear_width)); # define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c)) #endif #ifdef FEAT_VERTSPLIT static void draw_vsep_win __ARGS((win_T *wp, int row)); #endif #ifdef FEAT_STL_OPT static void redraw_custum_statusline __ARGS((win_T *wp)); #endif #ifdef FEAT_SEARCH_EXTRA static void start_search_hl __ARGS((void)); static void end_search_hl __ARGS((void)); static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum)); static void next_search_hl __ARGS((win_T *win, match_T *shl, linenr_T lnum, colnr_T mincol)); #endif static void screen_start_highlight __ARGS((int attr)); static void screen_char __ARGS((unsigned off, int row, int col)); #ifdef FEAT_MBYTE static void screen_char_2 __ARGS((unsigned off, int row, int col)); #endif static void screenclear2 __ARGS((void)); static void lineclear __ARGS((unsigned off, int width)); static void lineinvalid __ARGS((unsigned off, int width)); #ifdef FEAT_VERTSPLIT static void linecopy __ARGS((int to, int from, win_T *wp)); static void redraw_block __ARGS((int row, int end, win_T *wp)); #endif static int win_do_lines __ARGS((win_T *wp, int row, int line_count, int mayclear, int del)); static void win_rest_invalid __ARGS((win_T *wp)); static void msg_pos_mode __ARGS((void)); #if defined(FEAT_WINDOWS) static void draw_tabline __ARGS((void)); #endif #if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT) static int fillchar_status __ARGS((int *attr, int is_curwin)); #endif #ifdef FEAT_VERTSPLIT static int fillchar_vsep __ARGS((int *attr)); #endif #ifdef FEAT_STL_OPT static void win_redr_custom __ARGS((win_T *wp, int draw_ruler)); #endif #ifdef FEAT_CMDL_INFO static void win_redr_ruler __ARGS((win_T *wp, int always)); #endif #if defined(FEAT_CLIPBOARD) || defined(FEAT_VERTSPLIT) /* Ugly global: overrule attribute used by screen_char() */ static int screen_char_attr = 0; #endif /* * 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(type) int type; { redraw_win_later(curwin, type); } void redraw_win_later(wp, type) win_T *wp; int type; { if (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() { 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; } /* * Mark all windows to be redrawn later. */ void redraw_all_later(type) int type; { win_T *wp; FOR_ALL_WINDOWS(wp) { redraw_win_later(wp, type); } } /* * Mark all windows that are editing the current buffer to be updated later. */ void redraw_curbuf_later(type) int type; { redraw_buf_later(curbuf, type); } void redraw_buf_later(buf, type) buf_T *buf; int type; { win_T *wp; FOR_ALL_WINDOWS(wp) { if (wp->w_buffer == buf) redraw_win_later(wp, type); } } /* * 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. */ /*ARGSUSED*/ void redrawWinline(lnum, invalid) linenr_T lnum; int invalid; /* window line height is invalid now */ { #ifdef FEAT_FOLDING int i; #endif if (curwin->w_redraw_top == 0 || curwin->w_redraw_top > lnum) curwin->w_redraw_top = lnum; if (curwin->w_redraw_bot == 0 || curwin->w_redraw_bot < lnum) curwin->w_redraw_bot = lnum; redraw_later(VALID); #ifdef FEAT_FOLDING if (invalid) { /* A w_lines[] entry for this lnum has become invalid. */ i = find_wl_entry(curwin, lnum); if (i >= 0) curwin->w_lines[i].wl_valid = FALSE; } #endif } /* * update all windows that are editing the current buffer */ void update_curbuf(type) int type; { redraw_curbuf_later(type); update_screen(type); } /* * update_screen() * * Based on the current value of curwin->w_topline, transfer a screenfull * of stuff from Filemem to ScreenLines[], and update curwin->w_botline. */ void update_screen(type) int type; { win_T *wp; static int did_intro = FALSE; #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) int did_one; #endif if (!screen_valid(TRUE)) return; if (must_redraw) { if (type < must_redraw) /* use maximal type */ type = must_redraw; must_redraw = 0; } /* Need to update w_lines[]. */ if (curwin->w_lines_valid == 0 && type < NOT_VALID) type = NOT_VALID; if (!redrawing()) { 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; } updating_screen = TRUE; #ifdef FEAT_SYN_HL ++display_tick; /* let syntax code know we're in a next round of * display updating */ #endif /* * 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, NULL) == FAIL) type = CLEAR; FOR_ALL_WINDOWS(wp) { if (W_WINROW(wp) < 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; #ifdef FEAT_WINDOWS if (W_WINROW(wp) + wp->w_height + W_STATUS_HEIGHT(wp) <= msg_scrolled) wp->w_redr_status = TRUE; #endif } } } redraw_cmdline = TRUE; #ifdef FEAT_WINDOWS redraw_tabline = TRUE; #endif } 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; } if (clear_cmdline) /* going to clear cmdline (done below) */ check_for_delay(FALSE); #ifdef FEAT_LINEBREAK /* Force redraw when width of 'number' column changes. */ if (curwin->w_redr_type < NOT_VALID && curwin->w_nrwidth != (curwin->w_p_nu ? 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) #ifdef FEAT_VISUAL || (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) #endif )) curwin->w_redr_type = type; #ifdef FEAT_WINDOWS /* Redraw the tab pages line if needed. */ if (redraw_tabline || type >= NOT_VALID) draw_tabline(); #endif #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) { # ifdef FEAT_WINDOWS 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; # endif if ( # ifdef FEAT_WINDOWS wwp == wp && # endif syntax_present(wp->w_buffer)) syn_stack_apply_changes(wp->w_buffer); } } #endif /*