aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/screen.c')
-rw-r--r--src/nvim/screen.c1321
1 files changed, 645 insertions, 676 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index d9a21aa81f..2e64eb864f 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* screen.c: code for displaying on the screen
*
@@ -21,8 +24,6 @@
* cells the next byte in ScreenLines[] is 0.
* ScreenLinesC[][] contain up to 'maxcombine' composing characters
* (drawn on top of the first character). There is 0 after the last one 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[].
@@ -83,6 +84,7 @@
#include <stdbool.h>
#include <string.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/arabic.h"
@@ -102,6 +104,7 @@
#include "nvim/indent.h"
#include "nvim/getchar.h"
#include "nvim/main.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
@@ -128,16 +131,12 @@
#include "nvim/version.h"
#include "nvim/window.h"
#include "nvim/os/time.h"
+#include "nvim/api/private/helpers.h"
#define MB_FILLER_CHAR '<' /* character used when a double-width character
* doesn't fit. */
#define W_ENDCOL(wp) (wp->w_wincol + wp->w_width)
-/*
- * The attributes that are actually active for writing to the screen.
- */
-static int screen_attr = 0;
-
static match_T search_hl; /* used for 'hlsearch' highlight matching */
static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */
@@ -150,7 +149,6 @@ static schar_T *current_ScreenLine;
StlClickDefinition *tab_page_click_defs = NULL;
long tab_page_click_defs_size = 0;
-# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h"
#endif
@@ -184,8 +182,6 @@ void redraw_win_later(win_T *wp, int type)
void redraw_later_clear(void)
{
redraw_all_later(CLEAR);
- /* Use attributes that is very unlikely to appear in text. */
- screen_attr = HL_BOLD | HL_UNDERLINE | HL_INVERSE;
}
/*
@@ -302,13 +298,25 @@ void update_screen(int type)
* 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 */
+ clear_cmdline = true;
+ if (dy_flags & DY_MSGSEP) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ int valid = Rows - msg_scrollsize();
+ if (wp->w_winrow + wp->w_height > valid) {
+ wp->w_redr_type = NOT_VALID;
+ wp->w_lines_valid = 0;
+ }
+ if (wp->w_winrow + wp->w_height + wp->w_status_height > valid) {
+ wp->w_redr_status = true;
+ }
+ }
+ } else 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)
+ } 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_IN_TAB(wp, curtab) {
if (wp->w_winrow < msg_scrolled) {
if (wp->w_winrow + wp->w_height > msg_scrolled
@@ -340,8 +348,9 @@ void update_screen(int type)
if (need_highlight_changed)
highlight_changed();
- if (type == CLEAR) { /* first clear screen */
- screenclear(); /* will reset clear_cmdline */
+ if (type == CLEAR) { // first clear screen
+ screenclear(); // will reset clear_cmdline
+ cmdline_screen_cleared(); // clear external cmdline state
type = NOT_VALID;
}
@@ -375,15 +384,24 @@ void update_screen(int type)
))
curwin->w_redr_type = type;
- /* Redraw the tab pages line if needed. */
- if (redraw_tabline || type >= NOT_VALID)
+ // Redraw the tab pages line if needed.
+ if (redraw_tabline || type >= NOT_VALID) {
+ update_window_hl(curwin, type >= NOT_VALID);
+ FOR_ALL_TABS(tp) {
+ if (tp != curtab) {
+ update_window_hl(tp->tp_curwin, type >= NOT_VALID);
+ }
+ }
draw_tabline();
+ }
/*
* Correct stored syntax highlighting info for changes in each displayed
* buffer. Each buffer must only be done once.
*/
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ update_window_hl(wp, type >= NOT_VALID);
+
if (wp->w_buffer->b_mod_set) {
win_T *wwp;
@@ -678,12 +696,18 @@ static void win_update(win_T *wp)
if (wp->w_nrwidth != i) {
type = NOT_VALID;
wp->w_nrwidth = i;
- } else 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).
- */
+
+ if (buf->terminal) {
+ terminal_resize(buf->terminal,
+ (uint16_t)(MAX(0, wp->w_width - win_col_off(wp))),
+ (uint16_t)wp->w_height);
+ }
+ } else 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 {
/*
@@ -978,7 +1002,7 @@ static void win_update(win_T *wp)
* first. */
if (mid_start == 0) {
mid_end = wp->w_height;
- if (lastwin == firstwin) {
+ if (ONE_WINDOW) {
/* Clear the screen when it was not done by win_del_lines() or
* win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
* then. */
@@ -1015,14 +1039,10 @@ static void win_update(win_T *wp)
linenr_T from, to;
if (VIsual_active) {
- if (VIsual_active
- && (VIsual_mode != wp->w_old_visual_mode
- || type == INVERTED_ALL)) {
- /*
- * If the type of Visual selection changed, redraw the whole
- * selection. Also when the ownership of the X selection is
- * gained or lost.
- */
+ if (VIsual_mode != wp->w_old_visual_mode || type == INVERTED_ALL) {
+ // If the type of Visual selection changed, redraw the whole
+ // selection. Also when the ownership of the X selection is
+ // gained or lost.
if (curwin->w_cursor.lnum < VIsual.lnum) {
from = curwin->w_cursor.lnum;
to = VIsual.lnum;
@@ -1487,11 +1507,11 @@ static void win_update(win_T *wp)
// Last line isn't finished: Display "@@@" in the last screen line.
screen_puts_len((char_u *)"@@", 2, scr_row, wp->w_wincol,
- hl_attr(HLF_AT));
+ win_hl_attr(wp, HLF_AT));
screen_fill(scr_row, scr_row + 1,
(int)wp->w_wincol + 2, (int)W_ENDCOL(wp),
- '@', ' ', hl_attr(HLF_AT));
+ '@', ' ', win_hl_attr(wp, HLF_AT));
set_empty_rows(wp, srow);
wp->w_botline = lnum;
} else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline"
@@ -1499,7 +1519,7 @@ static void win_update(win_T *wp)
screen_fill(wp->w_winrow + wp->w_height - 1,
wp->w_winrow + wp->w_height,
W_ENDCOL(wp) - 3, W_ENDCOL(wp),
- '@', '@', hl_attr(HLF_AT));
+ '@', '@', win_hl_attr(wp, HLF_AT));
set_empty_rows(wp, srow);
wp->w_botline = lnum;
} else {
@@ -1572,6 +1592,20 @@ static void win_update(win_T *wp)
got_int = save_got_int;
}
+/// Returns width of the signcolumn that should be used for the whole window
+///
+/// @param wp window we want signcolumn width from
+/// @return max width of signcolumn (cell unit)
+///
+/// @note Returns a constant for now but hopefully we can improve neovim so that
+/// the returned value width adapts to the maximum number of marks to draw
+/// for the window
+/// TODO(teto)
+int win_signcol_width(win_T *wp)
+{
+ // 2 is vim default value
+ return 2;
+}
/*
* Clear the rest of the window and mark the unused lines with "c1". use "c2"
@@ -1583,6 +1617,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
# define FDC_OFF n
int fdc = compute_foldcolumn(wp, 0);
+ int attr = win_hl_attr(wp, hl);
+
if (wp->w_p_rl) {
// No check for cmdline window: should never be right-left.
n = fdc;
@@ -1593,11 +1629,11 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
n = wp->w_width;
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
W_ENDCOL(wp) - n, W_ENDCOL(wp),
- ' ', ' ', hl_attr(HLF_FC));
+ ' ', ' ', win_hl_attr(wp, HLF_FC));
}
if (signcolumn_on(wp)) {
- int nn = n + 2;
+ int nn = n + win_signcol_width(wp);
/* draw the sign column left of the fold column */
if (nn > wp->w_width) {
@@ -1605,16 +1641,16 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
W_ENDCOL(wp) - nn, W_ENDCOL(wp) - n,
- ' ', ' ', hl_attr(HLF_SC));
+ ' ', ' ', win_hl_attr(wp, HLF_SC));
n = nn;
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol, W_ENDCOL(wp) - 1 - FDC_OFF,
- c2, c2, hl_attr(hl));
+ c2, c2, attr);
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF,
- c1, c2, hl_attr(hl));
+ c1, c2, attr);
} else {
if (cmdwin_type != 0 && wp == curwin) {
/* draw the cmdline character in the leftmost column */
@@ -1623,7 +1659,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
n = wp->w_width;
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol, wp->w_wincol + n,
- cmdwin_type, ' ', hl_attr(HLF_AT));
+ cmdwin_type, ' ', win_hl_attr(wp, HLF_AT));
}
if (fdc > 0) {
int nn = n + fdc;
@@ -1633,12 +1669,12 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
nn = wp->w_width;
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol + n, wp->w_wincol + nn,
- ' ', ' ', hl_attr(HLF_FC));
+ ' ', ' ', win_hl_attr(wp, HLF_FC));
n = nn;
}
if (signcolumn_on(wp)) {
- int nn = n + 2;
+ int nn = n + win_signcol_width(wp);
/* draw the sign column after the fold column */
if (nn > wp->w_width) {
@@ -1646,13 +1682,13 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol + n, wp->w_wincol + nn,
- ' ', ' ', hl_attr(HLF_SC));
+ ' ', ' ', win_hl_attr(wp, HLF_SC));
n = nn;
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol + FDC_OFF, W_ENDCOL(wp),
- c1, c2, hl_attr(hl));
+ c1, c2, attr);
}
set_empty_rows(wp, row);
}
@@ -1687,7 +1723,7 @@ static int compute_foldcolumn(win_T *wp, int col)
*/
static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row)
{
- char_u buf[51];
+ char_u buf[FOLD_TEXT_LEN];
pos_T *top, *bot;
linenr_T lnume = lnum + fold_count - 1;
int len;
@@ -1714,10 +1750,9 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
*/
if (cmdwin_type != 0 && wp == curwin) {
ScreenLines[off] = cmdwin_type;
- ScreenAttrs[off] = hl_attr(HLF_AT);
- if (enc_utf8)
- ScreenLinesUC[off] = 0;
- ++col;
+ ScreenAttrs[off] = win_hl_attr(wp, HLF_AT);
+ ScreenLinesUC[off] = 0;
+ col++;
}
// 2. Add the 'foldcolumn'
@@ -1729,12 +1764,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
int i;
copy_text_attr(off + wp->w_width - fdc - col, buf, fdc,
- hl_attr(HLF_FC));
- /* reverse the fold column */
- for (i = 0; i < fdc; ++i)
+ win_hl_attr(wp, HLF_FC));
+ // reverse the fold column
+ for (i = 0; i < fdc; i++) {
ScreenLines[off + wp->w_width - i - 1 - col] = buf[i];
- } else
- copy_text_attr(off + col, buf, fdc, hl_attr(HLF_FC));
+ }
+ } else {
+ copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC));
+ }
col += fdc;
}
@@ -1747,16 +1784,18 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
/* Set all attributes of the 'number' or 'relativenumber' column and the
* text */
- RL_MEMSET(col, hl_attr(HLF_FL), wp->w_width - col);
+ RL_MEMSET(col, win_hl_attr(wp, HLF_FL), wp->w_width - col);
- // If signs are being displayed, add two spaces.
+ // If signs are being displayed, add spaces.
if (signcolumn_on(wp)) {
len = wp->w_width - col;
if (len > 0) {
- if (len > 2) {
- len = 2;
+ int len_max = win_signcol_width(wp);
+ if (len > len_max) {
+ len = len_max;
}
- copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_FL));
+ copy_text_attr(off + col, (char_u *)" ", len,
+ win_hl_attr(wp, HLF_FL));
col += len;
}
}
@@ -1788,13 +1827,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
}
}
- sprintf((char *)buf, fmt, w, num);
- if (wp->w_p_rl)
- /* the line number isn't reversed */
+ snprintf((char *)buf, FOLD_TEXT_LEN, fmt, w, num);
+ if (wp->w_p_rl) {
+ // the line number isn't reversed
copy_text_attr(off + wp->w_width - len - col, buf, len,
- hl_attr(HLF_FL));
- else
- copy_text_attr(off + col, buf, len, hl_attr(HLF_FL));
+ win_hl_attr(wp, HLF_FL));
+ } else {
+ copy_text_attr(off + col, buf, len, win_hl_attr(wp, HLF_FL));
+ }
col += len;
}
}
@@ -1876,12 +1916,10 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
}
if (cells > 1)
ScreenLines[idx + 1] = 0;
- } else if (enc_dbcs == DBCS_JPNU && *p == 0x8e)
- /* double-byte single width character */
- ScreenLines2[idx] = p[1];
- else if (cells > 1)
- /* double-width character */
+ } else if (cells > 1) {
+ // Double-width character.
ScreenLines[idx + 1] = p[1];
+ }
col += cells;
idx += cells;
p += c_len;
@@ -1909,10 +1947,15 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
if (fill_fold >= 0x80) {
ScreenLinesUC[off + col] = fill_fold;
ScreenLinesC[0][off + col] = 0;
- } else
+ ScreenLines[off + col] = 0x80; // avoid storing zero
+ } else {
ScreenLinesUC[off + col] = 0;
+ ScreenLines[off + col] = fill_fold;
+ }
+ col++;
+ } else {
+ ScreenLines[off + col++] = fill_fold;
}
- ScreenLines[off + col++] = fill_fold;
}
if (text != buf)
@@ -1952,12 +1995,12 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
len = wp->w_old_cursor_lcol;
else
len = wp->w_width - txtcol;
- RL_MEMSET(wp->w_old_cursor_fcol + txtcol, hl_attr(HLF_V),
- len - (int)wp->w_old_cursor_fcol);
+ RL_MEMSET(wp->w_old_cursor_fcol + txtcol, win_hl_attr(wp, HLF_V),
+ len - (int)wp->w_old_cursor_fcol);
}
} else {
- /* Set all attributes of the text */
- RL_MEMSET(txtcol, hl_attr(HLF_V), wp->w_width - txtcol);
+ // Set all attributes of the text
+ RL_MEMSET(txtcol, win_hl_attr(wp, HLF_V), wp->w_width - txtcol);
}
}
}
@@ -1977,7 +2020,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
}
if (txtcol >= 0 && txtcol < wp->w_width) {
ScreenAttrs[off + txtcol] =
- hl_combine_attr(ScreenAttrs[off + txtcol], hl_attr(HLF_MC));
+ hl_combine_attr(ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_MC));
}
txtcol = old_txtcol;
j = wp->w_p_cc_cols[++i];
@@ -1993,11 +2036,11 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
txtcol -= wp->w_leftcol;
if (txtcol >= 0 && txtcol < wp->w_width)
ScreenAttrs[off + txtcol] = hl_combine_attr(
- ScreenAttrs[off + txtcol], hl_attr(HLF_CUC));
+ ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_CUC));
}
- SCREEN_LINE(row + wp->w_winrow, wp->w_wincol, wp->w_width,
- wp->w_width, FALSE);
+ screen_line(row + wp->w_winrow, wp->w_wincol, wp->w_width,
+ wp->w_width, false, wp, 0);
/*
* Update w_cline_height and w_cline_folded if the cursor line was
@@ -2097,16 +2140,15 @@ win_line (
bool nochange /* not updating for changed text */
)
{
- int col; /* visual column on screen */
- unsigned off; /* offset in ScreenLines/ScreenAttrs */
- int c = 0; /* init for GCC */
- long vcol = 0; /* virtual column (for tabs) */
+ unsigned off; // offset in ScreenLines/ScreenAttrs
+ int c = 0; // init for GCC
+ long vcol = 0; // virtual column (for tabs)
long vcol_sbr = -1; // virtual column after showbreak
- long vcol_prev = -1; /* "vcol" of previous character */
- char_u *line; /* current line */
- char_u *ptr; /* current position in "line" */
- int row; /* row in the window, excl w_winrow */
- int screen_row; /* row on the screen, incl w_winrow */
+ long vcol_prev = -1; // "vcol" of previous character
+ char_u *line; // current line
+ char_u *ptr; // current position in "line"
+ int row; // row in the window, excl w_winrow
+ int screen_row; // row on the screen, incl w_winrow
char_u extra[18]; /* line number and 'fdc' must fit in here */
int n_extra = 0; /* number of extra chars */
@@ -2180,23 +2222,23 @@ win_line (
int change_start = MAXCOL; /* first col of changed area */
int change_end = -1; /* last col of changed area */
colnr_T trailcol = MAXCOL; /* start of trailing spaces */
- int need_showbreak = FALSE;
- int line_attr = 0; /* attribute for the whole line */
- matchitem_T *cur; /* points to the match list */
- match_T *shl; /* points to search_hl or a match */
- int shl_flag; /* flag to indicate whether search_hl
- has been processed or not */
- int prevcol_hl_flag; /* flag to indicate whether prevcol
- equals startcol of search_hl or one
- of the matches */
- int prev_c = 0; /* previous Arabic character */
- int prev_c1 = 0; /* first composing char for prev_c */
+ int need_showbreak = false; // overlong line, skip first x chars
+ int line_attr = 0; // attribute for the whole line
+ matchitem_T *cur; // points to the match list
+ match_T *shl; // points to search_hl or a match
+ int shl_flag; // flag to indicate whether search_hl
+ // has been processed or not
+ int prevcol_hl_flag; // flag to indicate whether prevcol
+ // equals startcol of search_hl or one
+ // of the matches
+ int prev_c = 0; // previous Arabic character
+ int prev_c1 = 0; // first composing char for prev_c
int did_line_attr = 0;
bool search_attr_from_match = false; // if search_attr is from :match
bool has_bufhl = false; // this buffer has highlight matches
int bufhl_attr = 0; // attributes desired by bufhl
- bufhl_lineinfo_T bufhl_info; // bufhl data for this line
+ BufhlLineInfo bufhl_info; // bufhl data for this line
/* draw_state: items that are drawn in sequence: */
#define WL_START 0 /* nothing done yet */
@@ -2212,7 +2254,7 @@ win_line (
int syntax_flags = 0;
int syntax_seqnr = 0;
int prev_syntax_id = 0;
- int conceal_attr = hl_attr(HLF_CONCEAL);
+ int conceal_attr = win_hl_attr(wp, HLF_CONCEAL);
int is_concealing = false;
int boguscols = 0; ///< nonexistent columns added to
///< force wrapping
@@ -2360,8 +2402,8 @@ win_line (
/* if inverting in this line set area_highlighting */
if (fromcol >= 0) {
- area_highlighting = TRUE;
- attr = hl_attr(HLF_V);
+ area_highlighting = true;
+ attr = win_hl_attr(wp, HLF_V);
}
}
/*
@@ -2385,8 +2427,8 @@ win_line (
/* do at least one character; happens when past end of line */
if (fromcol == tocol)
tocol = fromcol + 1;
- area_highlighting = TRUE;
- attr = hl_attr(HLF_I);
+ area_highlighting = true;
+ attr = win_hl_attr(wp, HLF_I);
}
filler_lines = diff_check(wp, lnum);
@@ -2407,14 +2449,15 @@ win_line (
filler_lines = wp->w_topfill;
filler_todo = filler_lines;
- /* If this line has a sign with line highlighting set line_attr. */
+ // If this line has a sign with line highlighting set line_attr.
v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL);
- if (v != 0)
- line_attr = sign_get_attr((int)v, TRUE);
+ if (v != 0) {
+ line_attr = sign_get_attr((int)v, true);
+ }
// Highlight the current line in the quickfix window.
if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) {
- line_attr = hl_attr(HLF_QFL);
+ line_attr = win_hl_attr(wp, HLF_QFL);
}
if (line_attr != 0) {
@@ -2448,7 +2491,7 @@ win_line (
} else {
/* Long line, use only the last SPWORDLEN bytes. */
nextlinecol = v - SPWORDLEN;
- memmove(nextline, line + nextlinecol, SPWORDLEN);
+ memmove(nextline, line + nextlinecol, SPWORDLEN); // -V512
nextline_idx = SPWORDLEN + 1;
}
}
@@ -2503,7 +2546,11 @@ win_line (
if (vcol > v) {
vcol -= c;
ptr = prev_ptr;
- n_skip = v - vcol;
+ // If the character fits on the screen, don't need to skip it.
+ // Except for a TAB.
+ if (utf_ptr2cells(ptr) >= c || *ptr == TAB) {
+ n_skip = v - vcol;
+ }
}
/*
@@ -2580,13 +2627,14 @@ win_line (
* Do this for both search_hl and the match list.
*/
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE) {
+ shl_flag = false;
+ while (cur != NULL || !shl_flag) {
+ if (!shl_flag) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
- shl = &cur->hl;
+ shl_flag = true;
+ } else {
+ shl = &cur->hl; // -V595
+ }
shl->startcol = MAXCOL;
shl->endcol = MAXCOL;
shl->attr_cur = 0;
@@ -2634,26 +2682,26 @@ win_line (
cur = cur->next;
}
- /* Cursor line highlighting for 'cursorline' in the current window. Not
- * when Visual mode is active, because it's not clear what is selected
- * then. */
+ // Cursor line highlighting for 'cursorline' in the current window. Not
+ // when Visual mode is active, because it's not clear what is selected
+ // then.
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
&& !(wp == curwin && VIsual_active)) {
if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer)
&& qf_current_entry(wp) == lnum) {
- line_attr = hl_combine_attr(hl_attr(HLF_CUL), line_attr);
+ line_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), line_attr);
} else {
- line_attr = hl_attr(HLF_CUL);
+ line_attr = win_hl_attr(wp, HLF_CUL);
}
area_highlighting = true;
}
off = (unsigned)(current_ScreenLine - ScreenLines);
- col = 0;
+ int col = 0; // Visual column on screen.
if (wp->w_p_rl) {
- /* Rightleft window: process the text in the normal direction, but put
- * it in current_ScreenLine[] from right to left. Start at the
- * rightmost column of the window. */
+ // Rightleft window: process the text in the normal direction, but put
+ // it in current_ScreenLine[] from right to left. Start at the
+ // rightmost column of the window.
col = wp->w_width - 1;
off += col;
}
@@ -2676,7 +2724,7 @@ win_line (
/* Draw the cmdline character. */
n_extra = 1;
c_extra = cmdwin_type;
- char_attr = hl_attr(HLF_AT);
+ char_attr = win_hl_attr(wp, HLF_AT);
}
}
@@ -2685,13 +2733,16 @@ win_line (
draw_state = WL_FOLD;
if (fdc > 0) {
- // Draw the 'foldcolumn'.
- fill_foldcolumn(extra, wp, false, lnum);
+ // Draw the 'foldcolumn'. Allocate a buffer, "extra" may
+ // already be in use.
+ xfree(p_extra_free);
+ p_extra_free = xmalloc(12 + 1);
+ fill_foldcolumn(p_extra_free, wp, false, lnum);
n_extra = fdc;
- p_extra = extra;
- p_extra[n_extra] = NUL;
+ p_extra_free[n_extra] = NUL;
+ p_extra = p_extra_free;
c_extra = NUL;
- char_attr = hl_attr(HLF_FC);
+ char_attr = win_hl_attr(wp, HLF_FC);
}
}
@@ -2702,18 +2753,25 @@ win_line (
* buffer or when using Netbeans. */
if (signcolumn_on(wp)) {
int text_sign;
- /* Draw two cells with the sign value or blank. */
+ // Draw cells with the sign value or blank.
c_extra = ' ';
- char_attr = hl_attr(HLF_SC);
- n_extra = 2;
+ char_attr = win_hl_attr(wp, HLF_SC);
+ n_extra = win_signcol_width(wp);
if (row == startrow + filler_lines && filler_todo <= 0) {
text_sign = buf_getsigntype(wp->w_buffer, lnum, SIGN_TEXT);
if (text_sign != 0) {
p_extra = sign_get_text(text_sign);
+ int symbol_blen = (int)STRLEN(p_extra);
if (p_extra != NULL) {
c_extra = NUL;
- n_extra = (int)STRLEN(p_extra);
+ // symbol(s) bytes + (filling spaces) (one byte each)
+ n_extra = symbol_blen +
+ (win_signcol_width(wp) - mb_string2cells(p_extra));
+ memset(extra, ' ', sizeof(extra));
+ STRNCPY(extra, p_extra, STRLEN(p_extra));
+ p_extra = extra;
+ p_extra[n_extra] = NUL;
}
char_attr = sign_get_attr(text_sign, FALSE);
}
@@ -2761,14 +2819,15 @@ win_line (
} else
c_extra = ' ';
n_extra = number_width(wp) + 1;
- char_attr = hl_attr(HLF_N);
- /* When 'cursorline' is set highlight the line number of
- * the current line differently.
- * TODO: Can we use CursorLine instead of CursorLineNr
- * when CursorLineNr isn't set? */
+ char_attr = win_hl_attr(wp, HLF_N);
+ // When 'cursorline' is set highlight the line number of
+ // the current line differently.
+ // TODO(vim): Can we use CursorLine instead of CursorLineNr
+ // when CursorLineNr isn't set?
if ((wp->w_p_cul || wp->w_p_rnu)
- && lnum == wp->w_cursor.lnum)
- char_attr = hl_attr(HLF_CLN);
+ && lnum == wp->w_cursor.lnum) {
+ char_attr = win_hl_attr(wp, HLF_CLN);
+ }
}
}
@@ -2784,13 +2843,15 @@ win_line (
// draw 'breakindent': indent wrapped text accodringly
if (draw_state == WL_BRI - 1 && n_extra == 0) {
draw_state = WL_BRI;
- if (wp->w_p_bri && n_extra == 0 && row != startrow && filler_lines == 0) {
- char_attr = 0; // was: hl_attr(HLF_AT);
+ // if need_showbreak is set, breakindent also applies
+ if (wp->w_p_bri && (row != startrow || need_showbreak)
+ && filler_lines == 0) {
+ char_attr = wp->w_hl_attr_normal;
if (diff_hlf != (hlf_T)0) {
- char_attr = hl_attr(diff_hlf);
+ char_attr = win_hl_attr(wp, diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
}
}
p_extra = NULL;
@@ -2815,15 +2876,15 @@ win_line (
n_extra = col + 1;
else
n_extra = wp->w_width - col;
- char_attr = hl_attr(HLF_DED);
+ char_attr = win_hl_attr(wp, HLF_DED);
}
if (*p_sbr != NUL && need_showbreak) {
/* Draw 'showbreak' at the start of each broken line. */
p_extra = p_sbr;
c_extra = NUL;
n_extra = (int)STRLEN(p_sbr);
- char_attr = hl_attr(HLF_AT);
- need_showbreak = FALSE;
+ char_attr = win_hl_attr(wp, HLF_AT);
+ need_showbreak = false;
vcol_sbr = vcol + MB_CHARLEN(p_sbr);
/* Correct end of highlighted area for 'showbreak',
* required when 'linebreak' is also set. */
@@ -2831,7 +2892,7 @@ win_line (
tocol += n_extra;
/* combine 'showbreak' with 'cursorline' */
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
}
}
}
@@ -2844,8 +2905,9 @@ win_line (
c_extra = saved_c_extra;
p_extra = saved_p_extra;
char_attr = saved_char_attr;
- } else
- char_attr = 0;
+ } else {
+ char_attr = wp->w_hl_attr_normal;
+ }
}
}
@@ -2854,13 +2916,15 @@ win_line (
&& lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol
&& filler_todo <= 0
) {
- SCREEN_LINE(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl);
- /* Pretend we have finished updating the window. Except when
- * 'cursorcolumn' is set. */
- if (wp->w_p_cuc)
+ screen_line(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl, wp,
+ wp->w_hl_attr_normal);
+ // Pretend we have finished updating the window. Except when
+ // 'cursorcolumn' is set.
+ if (wp->w_p_cuc) {
row = wp->w_cline_row + wp->w_cline_height;
- else
+ } else {
row = wp->w_height;
+ }
break;
}
@@ -2988,14 +3052,16 @@ win_line (
if (diff_hlf != (hlf_T)0) {
if (diff_hlf == HLF_CHD && ptr - line >= change_start
- && n_extra == 0)
- diff_hlf = HLF_TXD; /* changed text */
+ && n_extra == 0) {
+ diff_hlf = HLF_TXD; // changed text
+ }
if (diff_hlf == HLF_TXD && ptr - line > change_end
- && n_extra == 0)
- diff_hlf = HLF_CHD; /* changed line */
- line_attr = hl_attr(diff_hlf);
+ && n_extra == 0) {
+ diff_hlf = HLF_CHD; // changed line
+ }
+ line_attr = win_hl_attr(wp, diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- line_attr = hl_combine_attr(line_attr, hl_attr(HLF_CUL));
+ line_attr = hl_combine_attr(line_attr, win_hl_attr(wp, HLF_CUL));
}
}
@@ -3011,14 +3077,15 @@ win_line (
// (area_attr may be 0 when "noinvcur" is set).
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|| vcol < fromcol || vcol_prev < fromcol_prev
- || vcol >= tocol))
+ || vcol >= tocol)) {
char_attr = line_attr;
- else {
- attr_pri = FALSE;
- if (has_syntax)
+ } else {
+ attr_pri = false;
+ if (has_syntax) {
char_attr = syntax_attr;
- else
- char_attr = 0;
+ } else {
+ char_attr = wp->w_hl_attr_normal;
+ }
}
}
@@ -3079,12 +3146,13 @@ win_line (
c = '>';
mb_c = c;
mb_l = 1;
- mb_utf8 = FALSE;
- multi_attr = hl_attr(HLF_AT);
- /* put the pointer back to output the double-width
- * character at the start of the next line. */
- ++n_extra;
- --p_extra;
+ mb_utf8 = false;
+ multi_attr = win_hl_attr(wp, HLF_AT);
+
+ // put the pointer back to output the double-width
+ // character at the start of the next line.
+ n_extra++;
+ p_extra--;
} else {
n_extra -= mb_l - 1;
p_extra += mb_l - 1;
@@ -3094,14 +3162,15 @@ win_line (
}
--n_extra;
} else {
+ int c0;
+
if (p_extra_free != NULL) {
xfree(p_extra_free);
p_extra_free = NULL;
}
- /*
- * Get a character from the line itself.
- */
- c = *ptr;
+
+ // Get a character from the line itself.
+ c0 = c = *ptr;
if (has_mbyte) {
mb_c = c;
if (enc_utf8) {
@@ -3111,11 +3180,12 @@ win_line (
mb_utf8 = FALSE;
if (mb_l > 1) {
mb_c = utfc_ptr2char(ptr, u8cc);
- /* Overlong encoded ASCII or ASCII with composing char
- * is displayed normally, except a NUL. */
- if (mb_c < 0x80)
- c = mb_c;
- mb_utf8 = TRUE;
+ // Overlong encoded ASCII or ASCII with composing char
+ // is displayed normally, except a NUL.
+ if (mb_c < 0x80) {
+ c0 = c = mb_c;
+ }
+ mb_utf8 = true;
/* At start of the line we can have a composing char.
* Draw it as a space with a composing char. */
@@ -3134,9 +3204,9 @@ win_line (
|| (mb_l > 1 && (!vim_isprintc(mb_c)))) {
// Illegal UTF-8 byte: display as <xx>.
// Non-BMP character : display as ? or fullwidth ?.
- transchar_hex(extra, mb_c);
- if (wp->w_p_rl) { // reverse
- rl_mirror(extra);
+ transchar_hex((char *)extra, mb_c);
+ if (wp->w_p_rl) { // reverse
+ rl_mirror(extra);
}
p_extra = extra;
@@ -3147,8 +3217,8 @@ win_line (
c_extra = NUL;
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_8);
+ saved_attr2 = char_attr; // save current attr
}
} else if (mb_l == 0) /* at the NUL at end-of-line */
mb_l = 1;
@@ -3200,8 +3270,8 @@ win_line (
c = *p_extra++;
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_8);
+ saved_attr2 = char_attr; // save current attr
}
mb_c = c;
}
@@ -3218,12 +3288,13 @@ win_line (
mb_c = c;
mb_utf8 = FALSE;
mb_l = 1;
- multi_attr = hl_attr(HLF_AT);
- /* Put pointer back so that the character will be
- * displayed at the start of the next line. */
- --ptr;
- } else if (*ptr != NUL)
+ multi_attr = win_hl_attr(wp, HLF_AT);
+ // Put pointer back so that the character will be
+ // displayed at the start of the next line.
+ ptr--;
+ } else if (*ptr != NUL) {
ptr += mb_l - 1;
+ }
/* If a double-width char doesn't fit at the left side display
* a '<' in the first column. Don't do this for unprintable
@@ -3234,8 +3305,8 @@ win_line (
c = ' ';
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_AT);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_AT);
+ saved_attr2 = char_attr; // save current attr
}
mb_c = c;
mb_utf8 = FALSE;
@@ -3283,7 +3354,7 @@ win_line (
else
syntax_flags = get_syntax_info(&syntax_seqnr);
} else if (!attr_pri) {
- char_attr = 0;
+ char_attr = wp->w_hl_attr_normal;
}
/* Check spelling (unless at the end of the line).
@@ -3308,10 +3379,11 @@ win_line (
/* Use nextline[] if possible, it has the start of the
* next line concatenated. */
- if ((prev_ptr - line) - nextlinecol >= 0)
- p = nextline + (prev_ptr - line) - nextlinecol;
- else
+ if ((prev_ptr - line) - nextlinecol >= 0) {
+ p = nextline + ((prev_ptr - line) - nextlinecol);
+ } else {
p = prev_ptr;
+ }
cap_col -= (int)(prev_ptr - line);
size_t tmplen = spell_check(wp, p, &spell_hlf, &cap_col, nochange);
assert(tmplen <= INT_MAX);
@@ -3378,10 +3450,8 @@ win_line (
char_attr = hl_combine_attr(char_attr, term_attrs[vcol]);
}
- /*
- * Found last space before word: check for line break.
- */
- if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)) {
+ // Found last space before word: check for line break.
+ if (wp->w_p_lbr && c0 == c && vim_isbreak(c) && !vim_isbreak(*ptr)) {
int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0;
char_u *p = ptr - (mb_off + 1);
// TODO: is passing p for start of the line OK?
@@ -3409,7 +3479,7 @@ win_line (
|| (c == ' ' && lcs_space && ptr - line <= trailcol))) {
c = (c == ' ') ? lcs_space : lcs_nbsp;
n_attr = 1;
- extra_attr = hl_attr(HLF_0);
+ extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3424,7 +3494,7 @@ win_line (
if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') {
c = lcs_trail;
n_attr = 1;
- extra_attr = hl_attr(HLF_0);
+ extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3467,8 +3537,7 @@ win_line (
tab_len += vcol_off;
}
// boguscols before FIX_FOR_BOGUSCOLS macro from above.
- if (wp->w_p_list && lcs_tab1 && old_boguscols > 0
- && n_extra > tab_len) {
+ if (lcs_tab1 && old_boguscols > 0 && n_extra > tab_len) {
tab_len += n_extra - tab_len;
}
@@ -3482,6 +3551,7 @@ win_line (
p = xmalloc(len + 1);
memset(p, ' ', len);
p[len] = NUL;
+ xfree(p_extra_free);
p_extra_free = p;
for (i = 0; i < tab_len; i++) {
mb_char2bytes(lcs_tab2, p);
@@ -3525,7 +3595,7 @@ win_line (
c_extra = lcs_tab2;
}
n_attr = tab_len + 1;
- extra_attr = hl_attr(HLF_0);
+ extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3551,15 +3621,13 @@ win_line (
&& lcs_eol_one > 0) {
// Display a '$' after the line or highlight an extra
// character if the line break is included.
- // For a diff line the highlighting continues after the
- // "$".
+ // For a diff line the highlighting continues after the "$".
if (diff_hlf == (hlf_T)0 && line_attr == 0) {
- /* In virtualedit, visual selections may extend
- * beyond end of line. */
+ // In virtualedit, visual selections may extend beyond end of line.
if (area_highlighting && virtual_active()
- && tocol != MAXCOL && vcol < tocol)
+ && tocol != MAXCOL && vcol < tocol) {
n_extra = 0;
- else {
+ } else {
p_extra = at_end_str;
n_extra = 1;
c_extra = NUL;
@@ -3572,7 +3640,7 @@ win_line (
}
lcs_eol_one = -1;
ptr--; // put it back at the NUL
- extra_attr = hl_attr(HLF_AT);
+ extra_attr = win_hl_attr(wp, HLF_AT);
n_attr = 1;
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3597,13 +3665,14 @@ win_line (
memset(p, ' ', n_extra);
STRNCPY(p, p_extra + 1, STRLEN(p_extra) - 1);
p[n_extra] = NUL;
+ xfree(p_extra_free);
p_extra_free = p_extra = p;
} else {
n_extra = byte2cells(c) - 1;
c = *p_extra++;
}
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
+ extra_attr = win_hl_attr(wp, HLF_8);
saved_attr2 = char_attr; // save current attr
mb_utf8 = false; // don't draw as UTF-8
} else if (VIsual_active
@@ -3635,9 +3704,10 @@ win_line (
if (diff_hlf == HLF_TXD) {
diff_hlf = HLF_CHD;
if (attr == 0 || char_attr != attr) {
- char_attr = hl_attr(diff_hlf);
+ char_attr = win_hl_attr(wp, diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr,
+ win_hl_attr(wp, HLF_CUL));
}
}
}
@@ -3739,7 +3809,7 @@ win_line (
c_extra = MB_FILLER_CHAR;
n_extra = 1;
n_attr = 2;
- extra_attr = hl_attr(HLF_AT);
+ extra_attr = win_hl_attr(wp, HLF_AT);
}
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3750,7 +3820,7 @@ win_line (
mb_utf8 = false; // don't draw as UTF-8
}
saved_attr3 = char_attr; // save current attr
- char_attr = hl_attr(HLF_AT); // later copied to char_attr
+ char_attr = win_hl_attr(wp, HLF_AT); // overwriting char_attr
n_attr3 = 1;
}
@@ -3834,6 +3904,10 @@ win_line (
}
}
}
+
+ if (wp->w_hl_attr_normal != 0) {
+ char_attr = hl_combine_attr(wp->w_hl_attr_normal, char_attr);
+ }
ScreenAttrs[off] = char_attr;
if (wp->w_p_rl) {
--col;
@@ -3895,6 +3969,9 @@ win_line (
if (rightmost_vcol < color_cols[i])
rightmost_vcol = color_cols[i];
+ int cuc_attr = win_hl_attr(wp, HLF_CUC);
+ int mc_attr = win_hl_attr(wp, HLF_MC);
+
while (col < wp->w_width) {
ScreenLines[off] = ' ';
if (enc_utf8)
@@ -3904,12 +3981,13 @@ win_line (
draw_color_col = advance_color_col(VCOL_HLC,
&color_cols);
- if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol)
- ScreenAttrs[off++] = hl_attr(HLF_CUC);
- else if (draw_color_col && VCOL_HLC == *color_cols)
- ScreenAttrs[off++] = hl_attr(HLF_MC);
- else
- ScreenAttrs[off++] = 0;
+ if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol) {
+ ScreenAttrs[off++] = cuc_attr;
+ } else if (draw_color_col && VCOL_HLC == *color_cols) {
+ ScreenAttrs[off++] = mc_attr;
+ } else {
+ ScreenAttrs[off++] = wp->w_hl_attr_normal;
+ }
if (VCOL_HLC >= rightmost_vcol)
break;
@@ -3918,6 +3996,7 @@ win_line (
}
}
+ // TODO(bfredl): integrate with the common beyond-the-end-loop
if (wp->w_buffer->terminal) {
// terminal buffers may need to highlight beyond the end of the
// logical line
@@ -3930,7 +4009,8 @@ win_line (
col++;
}
}
- SCREEN_LINE(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl);
+ screen_line(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl, wp,
+ wp->w_hl_attr_normal);
row++;
/*
@@ -3958,7 +4038,7 @@ win_line (
|| (wp->w_p_list && lcs_eol_one > 0)
|| (n_extra && (c_extra != NUL || *p_extra != NUL)))) {
c = lcs_ext;
- char_attr = hl_attr(HLF_AT);
+ char_attr = win_hl_attr(wp, HLF_AT);
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = TRUE;
@@ -3981,10 +4061,10 @@ win_line (
if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol
&& lnum != wp->w_cursor.lnum) {
vcol_save_attr = char_attr;
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
+ char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUC), char_attr);
} else if (draw_color_col && VCOL_HLC == *color_cols) {
vcol_save_attr = char_attr;
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_MC));
+ char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), char_attr);
}
}
@@ -4003,24 +4083,19 @@ win_line (
--col;
}
ScreenLines[off] = c;
- if (enc_dbcs == DBCS_JPNU) {
- if ((mb_c & 0xff00) == 0x8e00)
- ScreenLines[off] = 0x8e;
- ScreenLines2[off] = mb_c & 0xff;
- } else if (enc_utf8) {
- if (mb_utf8) {
- int i;
-
- ScreenLinesUC[off] = mb_c;
- if ((c & 0xff) == 0)
- ScreenLines[off] = 0x80; /* avoid storing zero */
- for (i = 0; i < Screen_mco; ++i) {
- ScreenLinesC[i][off] = u8cc[i];
- if (u8cc[i] == 0)
- break;
+ if (mb_utf8) {
+ ScreenLinesUC[off] = mb_c;
+ if ((c & 0xff) == 0) {
+ ScreenLines[off] = 0x80; // Avoid storing zero.
+ }
+ for (int i = 0; i < Screen_mco; i++) {
+ ScreenLinesC[i][off] = u8cc[i];
+ if (u8cc[i] == 0) {
+ break;
}
- } else
- ScreenLinesUC[off] = 0;
+ }
+ } else {
+ ScreenLinesUC[off] = 0;
}
if (multi_attr) {
ScreenAttrs[off] = multi_attr;
@@ -4152,8 +4227,8 @@ win_line (
|| (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
|| (n_extra != 0 && (c_extra != NUL || *p_extra != NUL)))
) {
- SCREEN_LINE(screen_row, wp->w_wincol, col - boguscols,
- wp->w_width, wp->w_p_rl);
+ screen_line(screen_row, wp->w_wincol, col - boguscols,
+ wp->w_width, wp->w_p_rl, wp, wp->w_hl_attr_normal);
boguscols = 0;
++row;
++screen_row;
@@ -4193,7 +4268,6 @@ win_line (
* (regardless of the xn,am settings).
* Only do this if the cursor is on the current line
* (something has been written in it).
- * Don't do this for the GUI.
* Don't do this for double-width characters.
* Don't do this for a window not at the right screen border.
*/
@@ -4261,6 +4335,7 @@ win_line (
cap_col = 0;
}
+ xfree(p_extra_free);
return row;
}
@@ -4292,22 +4367,14 @@ static int comp_char_differs(int off_from, int off_to)
static int char_needs_redraw(int off_from, int off_to, int cols)
{
return (cols > 0
- && ((ScreenLines[off_from] != ScreenLines[off_to]
- || ScreenAttrs[off_from] != ScreenAttrs[off_to])
-
- || (enc_dbcs != 0
- && MB_BYTE2LEN(ScreenLines[off_from]) > 1
- && (enc_dbcs == DBCS_JPNU && ScreenLines[off_from] == 0x8e
- ? ScreenLines2[off_from] != ScreenLines2[off_to]
- : (cols > 1 && ScreenLines[off_from + 1]
- != ScreenLines[off_to + 1])))
- || (enc_utf8
- && (ScreenLinesUC[off_from] != ScreenLinesUC[off_to]
- || (ScreenLinesUC[off_from] != 0
- && comp_char_differs(off_from, off_to))
- || ((*mb_off2cells)(off_from, off_from + cols) > 1
- && ScreenLines[off_from + 1]
- != ScreenLines[off_to + 1])))));
+ && (ScreenLines[off_from] != ScreenLines[off_to]
+ || ScreenAttrs[off_from] != ScreenAttrs[off_to]
+ || ScreenLinesUC[off_from] != ScreenLinesUC[off_to]
+ || (ScreenLinesUC[off_from] != 0
+ && comp_char_differs(off_from, off_to))
+ || (utf_off2cells(off_from, off_from + cols) > 1
+ && ScreenLines[off_from + 1] != ScreenLines[off_to + 1])
+ || p_wd < 0));
}
/*
@@ -4321,7 +4388,8 @@ static int char_needs_redraw(int off_from, int off_to, int cols)
* When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
* When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
*/
-static void screen_line(int row, int coloff, int endcol, int clear_width, int rlflag)
+static void screen_line(int row, int coloff, int endcol,
+ int clear_width, int rlflag, win_T *wp, int bg_attr)
{
unsigned off_from;
unsigned off_to;
@@ -4354,15 +4422,16 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, int rl
/* Clear rest first, because it's left of the text. */
if (clear_width > 0) {
while (col <= endcol && ScreenLines[off_to] == ' '
- && ScreenAttrs[off_to] == 0
+ && ScreenAttrs[off_to] == bg_attr
&& (!enc_utf8 || ScreenLinesUC[off_to] == 0)
) {
++off_to;
++col;
}
- if (col <= endcol)
- screen_fill(row, row + 1, col + coloff,
- endcol + coloff + 1, ' ', ' ', 0);
+ if (col <= endcol) {
+ screen_fill(row, row + 1, col + coloff, endcol + coloff + 1, ' ', ' ',
+ bg_attr);
+ }
}
col = endcol + 1;
off_to = LineOffset[row] + col + coloff;
@@ -4370,6 +4439,13 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, int rl
endcol = (clear_width > 0 ? clear_width : -clear_width);
}
+ if (bg_attr) {
+ for (int c = col; c < endcol; c++) {
+ ScreenAttrs[off_from+c] = hl_combine_attr(bg_attr,
+ ScreenAttrs[off_from+c]);
+ }
+ }
+
redraw_next = char_needs_redraw(off_from, off_to, endcol - col);
while (col < endcol) {
@@ -4406,9 +4482,6 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, int rl
ScreenLines[off_to + 2] = 0;
redraw_next = TRUE;
}
-
- if (enc_dbcs == DBCS_JPNU)
- ScreenLines2[off_to] = ScreenLines2[off_from];
}
/* When writing a single-width character over a double-width
* character and at the end of the redrawn text, need to clear out
@@ -4468,26 +4541,26 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, int rl
/* blank out the rest of the line */
while (col < clear_width && ScreenLines[off_to] == ' '
- && ScreenAttrs[off_to] == 0
+ && ScreenAttrs[off_to] == bg_attr
&& (!enc_utf8 || ScreenLinesUC[off_to] == 0)
) {
++off_to;
++col;
}
if (col < clear_width) {
- screen_fill(row, row + 1, col + coloff, clear_width + coloff,
- ' ', ' ', 0);
+ screen_fill(row, row + 1, col + coloff, clear_width + coloff, ' ', ' ',
+ bg_attr);
off_to += clear_width - col;
col = clear_width;
}
}
if (clear_width > 0) {
- /* For a window that's left of another, draw the separator char. */
- if (col + coloff < Columns) {
+ // For a window that's left of another, draw the separator char.
+ if (col + coloff < Columns && wp->w_vsep_width > 0) {
int c;
- c = fillchar_vsep(&hl);
+ c = fillchar_vsep(wp, &hl);
if (ScreenLines[off_to] != (schar_T)c
|| (enc_utf8 && (int)ScreenLinesUC[off_to]
!= (c >= 0x80 ? c : 0))
@@ -4592,8 +4665,8 @@ static void draw_vsep_win(win_T *wp, int row)
int c;
if (wp->w_vsep_width) {
- /* draw the vertical separator right of this window */
- c = fillchar_vsep(&hl);
+ // draw the vertical separator right of this window
+ c = fillchar_vsep(wp, &hl);
screen_fill(wp->w_winrow + row, wp->w_winrow + wp->w_height,
W_ENDCOL(wp), W_ENDCOL(wp) + 1,
c, ' ', hl);
@@ -4723,7 +4796,7 @@ win_redr_status_matches (
--first_match;
}
- fillchar = fillchar_status(&attr, TRUE);
+ fillchar = fillchar_status(&attr, curwin);
if (first_match == 0) {
*buf = NUL;
@@ -4837,11 +4910,14 @@ void win_redr_status(win_T *wp)
int this_ru_col;
static int busy = FALSE;
- /* It's possible to get here recursively when 'statusline' (indirectly)
- * invokes ":redrawstatus". Simply ignore the call then. */
- if (busy)
+ // May get here recursively when 'statusline' (indirectly)
+ // invokes ":redrawstatus". Simply ignore the call then.
+ if (busy
+ // Also ignore if wildmenu is showing.
+ || (wild_menu_showing != 0 && !ui_is_external(kUIWildmenu))) {
return;
- busy = TRUE;
+ }
+ busy = true;
wp->w_redr_status = FALSE;
if (wp->w_status_height == 0) {
@@ -4855,7 +4931,7 @@ void win_redr_status(win_T *wp)
/* redraw custom status line */
redraw_custom_statusline(wp);
} else {
- fillchar = fillchar_status(&attr, wp == curwin);
+ fillchar = fillchar_status(&attr, wp);
get_trans_bufname(wp->w_buffer);
p = NameBuff;
@@ -4927,10 +5003,11 @@ void win_redr_status(win_T *wp)
* May need to draw the character below the vertical separator.
*/
if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing()) {
- if (stl_connected(wp))
- fillchar = fillchar_status(&attr, wp == curwin);
- else
- fillchar = fillchar_vsep(&attr);
+ if (stl_connected(wp)) {
+ fillchar = fillchar_status(&attr, wp);
+ } else {
+ fillchar = fillchar_vsep(wp, &attr);
+ }
screen_putchar(fillchar, wp->w_winrow + wp->w_height,
W_ENDCOL(wp), attr);
}
@@ -5080,7 +5157,7 @@ win_redr_custom (
use_sandbox = was_set_insecurely((char_u *)"tabline", 0);
} else {
row = wp->w_winrow + wp->w_height;
- fillchar = fillchar_status(&attr, wp == curwin);
+ fillchar = fillchar_status(&attr, wp);
maxwidth = wp->w_width;
if (draw_ruler) {
@@ -5137,8 +5214,8 @@ win_redr_custom (
xfree(stl);
ewp->w_p_crb = p_crb_save;
- /* Make all characters printable. */
- p = transstr(buf);
+ // Make all characters printable.
+ p = (char_u *)transstr((const char *)buf);
len = STRLCPY(buf, p, sizeof(buf));
len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1;
xfree(p);
@@ -5230,16 +5307,7 @@ void screen_getbytes(int row, int col, char_u *bytes, int *attrp)
bytes[0] = ScreenLines[off];
bytes[1] = NUL;
- if (enc_utf8 && ScreenLinesUC[off] != 0)
- bytes[utfc_char2bytes(off, bytes)] = NUL;
- else if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) {
- bytes[0] = ScreenLines[off];
- bytes[1] = ScreenLines2[off];
- bytes[2] = NUL;
- } else if (enc_dbcs && MB_BYTE2LEN(bytes[0]) > 1) {
- bytes[1] = ScreenLines[off + 1];
- bytes[2] = NUL;
- }
+ bytes[utfc_char2bytes(off, bytes)] = NUL;
}
}
@@ -5330,43 +5398,39 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
c = *ptr;
/* check if this is the first byte of a multibyte */
if (l_has_mbyte) {
- if (l_enc_utf8 && len > 0)
+ if (len > 0) {
mbyte_blen = utfc_ptr2len_len(ptr, (int)((text + len) - ptr));
- else
- mbyte_blen = (*mb_ptr2len)(ptr);
- if (l_enc_dbcs == DBCS_JPNU && c == 0x8e)
- mbyte_cells = 1;
- else if (l_enc_dbcs != 0)
- mbyte_cells = mbyte_blen;
- else { /* enc_utf8 */
- if (len >= 0)
- u8c = utfc_ptr2char_len(ptr, u8cc,
- (int)((text + len) - ptr));
- else
- u8c = utfc_ptr2char(ptr, u8cc);
- mbyte_cells = utf_char2cells(u8c);
- if (p_arshape && !p_tbidi && arabic_char(u8c)) {
- /* Do Arabic shaping. */
- if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) {
- /* Past end of string to be displayed. */
- nc = NUL;
- nc1 = NUL;
- } else {
- nc = utfc_ptr2char_len(ptr + mbyte_blen, pcc,
- (int)((text + len) - ptr - mbyte_blen));
- nc1 = pcc[0];
- }
- pc = prev_c;
- prev_c = u8c;
- u8c = arabic_shape(u8c, &c, &u8cc[0], nc, nc1, pc);
- } else
- prev_c = u8c;
- if (col + mbyte_cells > screen_Columns) {
- /* Only 1 cell left, but character requires 2 cells:
- * display a '>' in the last column to avoid wrapping. */
- c = '>';
- mbyte_cells = 1;
+ } else {
+ mbyte_blen = utfc_ptr2len(ptr);
+ }
+ if (len >= 0) {
+ u8c = utfc_ptr2char_len(ptr, u8cc, (int)((text + len) - ptr));
+ } else {
+ u8c = utfc_ptr2char(ptr, u8cc);
+ }
+ mbyte_cells = utf_char2cells(u8c);
+ if (p_arshape && !p_tbidi && arabic_char(u8c)) {
+ // Do Arabic shaping.
+ if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) {
+ // Past end of string to be displayed.
+ nc = NUL;
+ nc1 = NUL;
+ } else {
+ nc = utfc_ptr2char_len(ptr + mbyte_blen, pcc,
+ (int)((text + len) - ptr - mbyte_blen));
+ nc1 = pcc[0];
}
+ pc = prev_c;
+ prev_c = u8c;
+ u8c = arabic_shape(u8c, &c, &u8cc[0], nc, nc1, pc);
+ } else {
+ prev_c = u8c;
+ }
+ if (col + mbyte_cells > screen_Columns) {
+ // Only 1 cell left, but character requires 2 cells:
+ // display a '>' in the last column to avoid wrapping. */
+ c = '>';
+ mbyte_cells = 1;
}
}
@@ -5374,16 +5438,11 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
force_redraw_next = FALSE;
need_redraw = ScreenLines[off] != c
- || (mbyte_cells == 2
- && ScreenLines[off + 1] != (l_enc_dbcs ? ptr[1] : 0))
- || (l_enc_dbcs == DBCS_JPNU
- && c == 0x8e
- && ScreenLines2[off] != ptr[1])
- || (l_enc_utf8
- && (ScreenLinesUC[off] !=
- (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c)
- || (ScreenLinesUC[off] != 0
- && screen_comp_differs(off, u8cc))))
+ || (mbyte_cells == 2 && ScreenLines[off + 1] != 0)
+ || (ScreenLinesUC[off] !=
+ (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c)
+ || (ScreenLinesUC[off] != 0
+ && screen_comp_differs(off, u8cc)))
|| ScreenAttrs[off] != attr
|| exmode_active;
@@ -5438,11 +5497,9 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
ScreenLines[off + 1] = ptr[1];
ScreenAttrs[off + 1] = attr;
screen_char_2(off, row, col);
- } else if (l_enc_dbcs == DBCS_JPNU && c == 0x8e) {
- ScreenLines2[off] = ptr[1];
- screen_char(off, row, col);
- } else
+ } else {
screen_char(off, row, col);
+ }
}
if (l_has_mbyte) {
off += mbyte_cells;
@@ -5474,8 +5531,7 @@ static void start_search_hl(void)
{
if (p_hls && !no_hlsearch) {
last_pat_prog(&search_hl.rm);
- search_hl.attr = hl_attr(HLF_L);
- /* Set the time limit to 'redrawtime'. */
+ // Set the time limit to 'redrawtime'.
search_hl.tm = profile_setlimit(p_rdt);
}
}
@@ -5491,6 +5547,42 @@ static void end_search_hl(void)
}
}
+static void update_window_hl(win_T *wp, bool invalid)
+{
+ if (!wp->w_hl_needs_update && !invalid) {
+ return;
+ }
+ wp->w_hl_needs_update = false;
+
+ // determine window specific background set in 'winhighlight'
+ if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] > 0) {
+ wp->w_hl_attr_normal = syn_id2attr(wp->w_hl_ids[HLF_INACTIVE]);
+ } else if (wp->w_hl_id_normal > 0) {
+ wp->w_hl_attr_normal = syn_id2attr(wp->w_hl_id_normal);
+ } else {
+ wp->w_hl_attr_normal = 0;
+ }
+ if (wp != curwin) {
+ wp->w_hl_attr_normal = hl_combine_attr(hl_attr(HLF_INACTIVE),
+ wp->w_hl_attr_normal);
+ }
+
+ for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ int attr;
+ if (wp->w_hl_ids[hlf] > 0) {
+ attr = syn_id2attr(wp->w_hl_ids[hlf]);
+ } else {
+ attr = hl_attr(hlf);
+ }
+ if (wp->w_hl_attr_normal != 0) {
+ attr = hl_combine_attr(wp->w_hl_attr_normal, attr);
+ }
+ wp->w_hl_attrs[hlf] = attr;
+ }
+}
+
+
+
/*
* Init for calling prepare_search_hl().
*/
@@ -5517,7 +5609,9 @@ static void init_search_hl(win_T *wp)
search_hl.buf = wp->w_buffer;
search_hl.lnum = 0;
search_hl.first_lnum = 0;
- /* time limit is set at the toplevel, for all windows */
+ search_hl.attr = win_hl_attr(wp, HLF_L);
+
+ // time limit is set at the toplevel, for all windows
}
/*
@@ -5537,13 +5631,14 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
* Do this both for search_hl and the match list.
*/
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE) {
+ shl_flag = false;
+ while (cur != NULL || shl_flag == false) {
+ if (shl_flag == false) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
- shl = &cur->hl;
+ shl_flag = true;
+ } else {
+ shl = &cur->hl; // -V595
+ }
if (shl->rm.regprog != NULL
&& shl->lnum == 0
&& re_multiline(shl->rm.regprog)) {
@@ -5753,54 +5848,31 @@ next_search_hl_pos(
return 0;
}
-static void screen_start_highlight(int attr)
-{
- screen_attr = attr;
- ui_start_highlight(attr);
-}
-
-void screen_stop_highlight(void)
-{
- ui_stop_highlight();
- screen_attr = 0;
-}
-
/*
* Put character ScreenLines["off"] on the screen at position "row" and "col",
* using the attributes from ScreenAttrs["off"].
*/
static void screen_char(unsigned off, int row, int col)
{
- int attr;
-
- /* Check for illegal values, just in case (could happen just after
- * resizing). */
- if (row >= screen_Rows || col >= screen_Columns)
+ // Check for illegal values, just in case (could happen just after resizing).
+ if (row >= screen_Rows || col >= screen_Columns) {
return;
+ }
- /* Outputting the last character on the screen may scrollup the screen.
- * Don't to it! Mark the character invalid (update it when scrolled up) */
+ // Outputting the last character on the screen may scrollup the screen.
+ // Don't to it! Mark the character invalid (update it when scrolled up)
+ // FIXME: The premise here is not actually true (cf. deferred wrap).
if (row == screen_Rows - 1 && col == screen_Columns - 1
- /* account for first command-line character in rightleft mode */
- && !cmdmsg_rl
- ) {
+ // account for first command-line character in rightleft mode
+ && !cmdmsg_rl) {
ScreenAttrs[off] = (sattr_T)-1;
return;
}
- /*
- * Stop highlighting first, so it's easier to move the cursor.
- */
- attr = ScreenAttrs[off];
- if (screen_attr != attr)
- screen_stop_highlight();
-
ui_cursor_goto(row, col);
+ ui_set_highlight(ScreenAttrs[off]);
- if (screen_attr != attr)
- screen_start_highlight(attr);
-
- if (enc_utf8 && ScreenLinesUC[off] != 0) {
+ if (ScreenLinesUC[off] != 0) {
char_u buf[MB_MAXBYTES + 1];
// Convert UTF-8 character to bytes and write it.
@@ -5808,10 +5880,6 @@ static void screen_char(unsigned off, int row, int col)
ui_puts(buf);
} else {
ui_putc(ScreenLines[off]);
- // double-byte character in single-width cell
- if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) {
- ui_putc(ScreenLines2[off]);
- }
}
}
@@ -5907,9 +5975,9 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
++off;
if (off < end_off) { /* something to be cleared */
col = off - LineOffset[row];
- screen_stop_highlight();
+ ui_clear_highlight();
ui_cursor_goto(row, col); // clear rest of this screen line
- ui_eol_clear();
+ ui_call_eol_clear();
col = end_col - col;
while (col--) { /* clear chars in ScreenLines */
ScreenLines[off] = ' ';
@@ -6003,40 +6071,25 @@ int screen_valid(int doclear)
void screenalloc(bool doclear)
{
int new_row, old_row;
- int outofmem = FALSE;
int len;
- schar_T *new_ScreenLines;
- u8char_T *new_ScreenLinesUC = NULL;
- u8char_T *new_ScreenLinesC[MAX_MCO];
- schar_T *new_ScreenLines2 = NULL;
- int i;
- sattr_T *new_ScreenAttrs;
- unsigned *new_LineOffset;
- char_u *new_LineWraps;
- StlClickDefinition *new_tab_page_click_defs;
static bool entered = false; // avoid recursiveness
static bool done_outofmem_msg = false;
int retry_count = 0;
- const bool l_enc_utf8 = enc_utf8;
- const int l_enc_dbcs = enc_dbcs;
retry:
- /*
- * Allocation of the screen buffers is done only when the size changes and
- * when Rows and Columns have been set and we have started doing full
- * screen stuff.
- */
+ // Allocation of the screen buffers is done only when the size changes and
+ // when Rows and Columns have been set and we have started doing full
+ // screen stuff.
if ((ScreenLines != NULL
&& Rows == screen_Rows
&& Columns == screen_Columns
- && l_enc_utf8 == (ScreenLinesUC != NULL)
- && (l_enc_dbcs == DBCS_JPNU) == (ScreenLines2 != NULL)
- && p_mco == Screen_mco
- )
+ && ScreenLinesUC != NULL
+ && p_mco == Screen_mco)
|| Rows == 0
|| Columns == 0
- || (!full_screen && ScreenLines == NULL))
+ || (!full_screen && ScreenLines == NULL)) {
return;
+ }
/*
* It's possible that we produce an out-of-memory message below, which
@@ -6074,22 +6127,22 @@ retry:
if (aucmd_win != NULL)
win_free_lsize(aucmd_win);
- new_ScreenLines = xmalloc((size_t)((Rows + 1) * Columns * sizeof(schar_T)));
- memset(new_ScreenLinesC, 0, sizeof(u8char_T *) * MAX_MCO);
- if (l_enc_utf8) {
- new_ScreenLinesUC = xmalloc(
- (size_t)((Rows + 1) * Columns * sizeof(u8char_T)));
- for (i = 0; i < p_mco; ++i)
- new_ScreenLinesC[i] = xcalloc((Rows + 1) * Columns, sizeof(u8char_T));
- }
- if (l_enc_dbcs == DBCS_JPNU)
- new_ScreenLines2 = xmalloc(
- (size_t)((Rows + 1) * Columns * sizeof(schar_T)));
- new_ScreenAttrs = xmalloc((size_t)((Rows + 1) * Columns * sizeof(sattr_T)));
- new_LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned)));
- new_LineWraps = xmalloc((size_t)(Rows * sizeof(char_u)));
- new_tab_page_click_defs = xcalloc(
- (size_t) Columns, sizeof(*new_tab_page_click_defs));
+ schar_T *new_ScreenLines = xmalloc(
+ (size_t)((Rows + 1) * Columns * sizeof(*new_ScreenLines)));
+ u8char_T *new_ScreenLinesC[MAX_MCO];
+ memset(new_ScreenLinesC, 0, sizeof(new_ScreenLinesC));
+ u8char_T *new_ScreenLinesUC = xmalloc(
+ (size_t)((Rows + 1) * Columns * sizeof(*new_ScreenLinesUC)));
+ for (int i = 0; i < p_mco; i++) {
+ new_ScreenLinesC[i] = xcalloc(
+ (size_t)((Rows + 1) * Columns), sizeof(new_ScreenLinesC[0][0]));
+ }
+ sattr_T *new_ScreenAttrs = xmalloc(
+ (size_t)((Rows + 1) * Columns * sizeof(*new_ScreenAttrs)));
+ unsigned *new_LineOffset = xmalloc((size_t)(Rows * sizeof(*new_LineOffset)));
+ char_u *new_LineWraps = xmalloc((size_t)(Rows * sizeof(*new_LineWraps)));
+ StlClickDefinition *new_tab_page_click_defs = xcalloc(
+ (size_t)Columns, sizeof(*new_tab_page_click_defs));
FOR_ALL_TAB_WINDOWS(tp, wp) {
win_alloc_lines(wp);
@@ -6098,24 +6151,20 @@ retry:
win_alloc_lines(aucmd_win);
}
- for (i = 0; i < p_mco; ++i)
- if (new_ScreenLinesC[i] == NULL)
+ int i;
+ for (i = 0; i < p_mco; i++) {
+ if (new_ScreenLinesC[i] == NULL) {
break;
- if (new_ScreenLines == NULL
- || (l_enc_utf8 && (new_ScreenLinesUC == NULL || i != p_mco))
- || (l_enc_dbcs == DBCS_JPNU && new_ScreenLines2 == NULL)
- || new_ScreenAttrs == NULL
- || new_LineOffset == NULL
- || new_LineWraps == NULL
- || new_tab_page_click_defs == NULL
- || outofmem) {
+ }
+ }
+ if (i != p_mco) {
if (ScreenLines != NULL || !done_outofmem_msg) {
- /* guess the size */
+ // Guess the size.
do_outofmem_msg((Rows + 1) * Columns);
- /* Remember we did this to avoid getting outofmem messages over
- * and over again. */
- done_outofmem_msg = TRUE;
+ // Remember we did this to avoid getting outofmem messages over
+ // and over again.
+ done_outofmem_msg = true;
}
xfree(new_ScreenLines);
new_ScreenLines = NULL;
@@ -6125,8 +6174,6 @@ retry:
xfree(new_ScreenLinesC[i]);
new_ScreenLinesC[i] = NULL;
}
- xfree(new_ScreenLines2);
- new_ScreenLines2 = NULL;
xfree(new_ScreenAttrs);
new_ScreenAttrs = NULL;
xfree(new_LineOffset);
@@ -6149,52 +6196,42 @@ retry:
* executing an external command, for the GUI).
*/
if (!doclear) {
- (void)memset(new_ScreenLines + new_row * Columns,
- ' ', (size_t)Columns * sizeof(schar_T));
- if (l_enc_utf8) {
- (void)memset(new_ScreenLinesUC + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- (void)memset(new_ScreenLinesC[i]
- + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
+ memset(new_ScreenLines + new_row * Columns,
+ ' ', (size_t)Columns * sizeof(new_ScreenLines[0]));
+ memset(new_ScreenLinesUC + new_row * Columns,
+ 0, (size_t)Columns * sizeof(new_ScreenLinesUC[0]));
+ for (i = 0; i < p_mco; i++) {
+ memset(new_ScreenLinesC[i] + new_row * Columns,
+ 0, (size_t)Columns * sizeof(new_ScreenLinesC[0][0]));
}
- if (l_enc_dbcs == DBCS_JPNU)
- (void)memset(new_ScreenLines2 + new_row * Columns,
- 0, (size_t)Columns * sizeof(schar_T));
- (void)memset(new_ScreenAttrs + new_row * Columns,
- 0, (size_t)Columns * sizeof(sattr_T));
+ memset(new_ScreenAttrs + new_row * Columns,
+ 0, (size_t)Columns * sizeof(new_ScreenAttrs[0]));
old_row = new_row + (screen_Rows - Rows);
if (old_row >= 0 && ScreenLines != NULL) {
if (screen_Columns < Columns)
len = screen_Columns;
else
len = Columns;
- /* When switching to utf-8 don't copy characters, they
- * may be invalid now. Also when p_mco changes. */
- if (!(l_enc_utf8 && ScreenLinesUC == NULL)
- && p_mco == Screen_mco)
+ // When switching to utf-8 don't copy characters, they
+ // may be invalid now. Also when p_mco changes.
+ if (ScreenLinesUC != NULL && p_mco == Screen_mco) {
memmove(new_ScreenLines + new_LineOffset[new_row],
- ScreenLines + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
- if (l_enc_utf8 && ScreenLinesUC != NULL
- && p_mco == Screen_mco) {
+ ScreenLines + LineOffset[old_row],
+ (size_t)len * sizeof(new_ScreenLines[0]));
+ }
+ if (ScreenLinesUC != NULL && p_mco == Screen_mco) {
memmove(new_ScreenLinesUC + new_LineOffset[new_row],
- ScreenLinesUC + LineOffset[old_row],
- (size_t)len * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- memmove(new_ScreenLinesC[i]
- + new_LineOffset[new_row],
- ScreenLinesC[i] + LineOffset[old_row],
- (size_t)len * sizeof(u8char_T));
+ ScreenLinesUC + LineOffset[old_row],
+ (size_t)len * sizeof(new_ScreenLinesUC[0]));
+ for (i = 0; i < p_mco; i++) {
+ memmove(new_ScreenLinesC[i] + new_LineOffset[new_row],
+ ScreenLinesC[i] + LineOffset[old_row],
+ (size_t)len * sizeof(new_ScreenLinesC[0][0]));
+ }
}
- if (l_enc_dbcs == DBCS_JPNU && ScreenLines2 != NULL)
- memmove(new_ScreenLines2 + new_LineOffset[new_row],
- ScreenLines2 + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
memmove(new_ScreenAttrs + new_LineOffset[new_row],
- ScreenAttrs + LineOffset[old_row],
- (size_t)len * sizeof(sattr_T));
+ ScreenAttrs + LineOffset[old_row],
+ (size_t)len * sizeof(new_ScreenAttrs[0]));
}
}
}
@@ -6209,7 +6246,6 @@ retry:
for (i = 0; i < p_mco; ++i)
ScreenLinesC[i] = new_ScreenLinesC[i];
Screen_mco = p_mco;
- ScreenLines2 = new_ScreenLines2;
ScreenAttrs = new_ScreenAttrs;
LineOffset = new_LineOffset;
LineWraps = new_LineWraps;
@@ -6243,12 +6279,10 @@ retry:
void free_screenlines(void)
{
- int i;
-
xfree(ScreenLinesUC);
- for (i = 0; i < Screen_mco; ++i)
+ for (int i = 0; i < Screen_mco; i++) {
xfree(ScreenLinesC[i]);
- xfree(ScreenLines2);
+ }
xfree(ScreenLines);
xfree(ScreenAttrs);
xfree(LineOffset);
@@ -6289,8 +6323,7 @@ static void screenclear2(void)
return;
}
- screen_stop_highlight(); /* don't want highlighting here */
-
+ ui_clear_highlight(); // don't want highlighting here
/* blank out ScreenLines */
for (i = 0; i < Rows; ++i) {
@@ -6298,10 +6331,10 @@ static void screenclear2(void)
LineWraps[i] = FALSE;
}
- ui_clear(); // clear the display
- clear_cmdline = FALSE;
- mode_displayed = FALSE;
- screen_cleared = TRUE; /* can use contents of ScreenLines now */
+ ui_call_clear(); // clear the display
+ clear_cmdline = false;
+ mode_displayed = false;
+ screen_cleared = true; // can use contents of ScreenLines now
win_rest_invalid(firstwin);
redraw_cmdline = TRUE;
@@ -6333,25 +6366,21 @@ static void lineclear(unsigned off, int width)
*/
static void linecopy(int to, int from, win_T *wp)
{
- unsigned off_to = LineOffset[to] + wp->w_wincol;
- unsigned off_from = LineOffset[from] + wp->w_wincol;
+ const unsigned off_to = LineOffset[to] + wp->w_wincol;
+ const unsigned off_from = LineOffset[from] + wp->w_wincol;
memmove(ScreenLines + off_to, ScreenLines + off_from,
- wp->w_width * sizeof(schar_T));
- if (enc_utf8) {
- int i;
+ wp->w_width * sizeof(ScreenLines[0]));
- memmove(ScreenLinesUC + off_to, ScreenLinesUC + off_from,
- wp->w_width * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- memmove(ScreenLinesC[i] + off_to, ScreenLinesC[i] + off_from,
- wp->w_width * sizeof(u8char_T));
+ memmove(ScreenLinesUC + off_to, ScreenLinesUC + off_from,
+ wp->w_width * sizeof(ScreenLinesUC[0]));
+ for (int i = 0; i < p_mco; i++) {
+ memmove(ScreenLinesC[i] + off_to, ScreenLinesC[i] + off_from,
+ wp->w_width * sizeof(ScreenLinesC[0]));
}
- if (enc_dbcs == DBCS_JPNU)
- memmove(ScreenLines2 + off_to, ScreenLines2 + off_from,
- wp->w_width * sizeof(schar_T));
+
memmove(ScreenAttrs + off_to, ScreenAttrs + off_from,
- wp->w_width * sizeof(sattr_T));
+ wp->w_width * sizeof(ScreenAttrs[0]));
}
/*
@@ -6374,125 +6403,39 @@ void setcursor(void)
}
}
-/*
- * insert 'line_count' lines at 'row' in window 'wp'
- * if 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated.
- * if 'mayclear' is TRUE the screen will be cleared if it is faster than
- * scrolling.
- * Returns FAIL if the lines are not inserted, OK for success.
- */
+/// Insert 'line_count' lines at 'row' in window 'wp'.
+/// If 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated.
+/// If 'mayclear' is TRUE the screen will be cleared if it is faster than
+/// scrolling.
+/// Returns FAIL if the lines are not inserted, OK for success.
int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
{
- int did_delete;
- int nextrow;
- int lastrow;
- int retval;
-
- if (invalid)
- wp->w_lines_valid = 0;
-
- if (wp->w_height < 5)
- return FAIL;
-
- if (line_count > wp->w_height - row)
- line_count = wp->w_height - row;
-
- retval = win_do_lines(wp, row, line_count, mayclear, FALSE);
- if (retval != MAYBE)
- return retval;
-
- /*
- * If there is a next window or a status line, we first try to delete the
- * lines at the bottom to avoid messing what is after the window.
- * If this fails and there are following windows, don't do anything to avoid
- * messing up those windows, better just redraw.
- */
- did_delete = FALSE;
- if (wp->w_next != NULL || wp->w_status_height) {
- if (screen_del_lines(0, wp->w_winrow + wp->w_height - line_count,
- line_count, (int)Rows, NULL) == OK)
- did_delete = TRUE;
- else if (wp->w_next)
- return FAIL;
- }
- /*
- * if no lines deleted, blank the lines that will end up below the window
- */
- if (!did_delete) {
- wp->w_redr_status = TRUE;
- redraw_cmdline = TRUE;
- nextrow = wp->w_winrow + wp->w_height + wp->w_status_height;
- lastrow = nextrow + line_count;
- if (lastrow > Rows)
- lastrow = Rows;
- screen_fill(nextrow - line_count, lastrow - line_count,
- wp->w_wincol, W_ENDCOL(wp),
- ' ', ' ', 0);
- }
-
- if (screen_ins_lines(0, wp->w_winrow + row, line_count, (int)Rows, NULL)
- == FAIL) {
- /* deletion will have messed up other windows */
- if (did_delete) {
- wp->w_redr_status = TRUE;
- win_rest_invalid(wp->w_next);
- }
+ if (wp->w_height < 5) {
return FAIL;
}
- return OK;
+ return win_do_lines(wp, row, line_count, invalid, mayclear, false);
}
-/*
- * delete "line_count" window lines at "row" in window "wp"
- * If "invalid" is TRUE curwin->w_lines[] is invalidated.
- * If "mayclear" is TRUE the screen will be cleared if it is faster than
- * scrolling
- * Return OK for success, FAIL if the lines are not deleted.
- */
+/// Delete "line_count" window lines at "row" in window "wp".
+/// If "invalid" is TRUE curwin->w_lines[] is invalidated.
+/// If "mayclear" is TRUE the screen will be cleared if it is faster than
+/// scrolling
+/// Return OK for success, FAIL if the lines are not deleted.
int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
{
- int retval;
-
- if (invalid)
- wp->w_lines_valid = 0;
-
- if (line_count > wp->w_height - row)
- line_count = wp->w_height - row;
-
- retval = win_do_lines(wp, row, line_count, mayclear, TRUE);
- if (retval != MAYBE)
- return retval;
-
- if (screen_del_lines(0, wp->w_winrow + row, line_count,
- (int)Rows, NULL) == FAIL) {
- return FAIL;
- }
-
- /*
- * If there are windows or status lines below, try to put them at the
- * correct place. If we can't do that, they have to be redrawn.
- */
- if (wp->w_next || wp->w_status_height || cmdline_row < Rows - 1) {
- if (screen_ins_lines(0, wp->w_winrow + wp->w_height - line_count,
- line_count, (int)Rows, NULL) == FAIL) {
- wp->w_redr_status = TRUE;
- win_rest_invalid(wp->w_next);
- }
- }
- /*
- * If this is the last window and there is no status line, redraw the
- * command line later.
- */
- else
- redraw_cmdline = TRUE;
- return OK;
+ return win_do_lines(wp, row, line_count, invalid, mayclear, true);
}
// Common code for win_ins_lines() and win_del_lines().
// Returns OK or FAIL when the work has been done.
-static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int del)
+static int win_do_lines(win_T *wp, int row, int line_count,
+ int invalid, int mayclear, int del)
{
+ if (invalid) {
+ wp->w_lines_valid = 0;
+ }
+
if (!redrawing() || line_count <= 0) {
return FAIL;
}
@@ -6600,7 +6543,7 @@ int screen_ins_lines (
}
}
- ui_append_lines(line_count);
+ ui_call_scroll(-line_count);
return OK;
}
@@ -6655,7 +6598,7 @@ int screen_del_lines (
}
}
- ui_delete_lines(line_count);
+ ui_call_scroll(line_count);
return OK;
}
@@ -6728,7 +6671,7 @@ int showmode(void)
if (edit_submode_extra != NULL) {
MSG_PUTS_ATTR(" ", attr); // Add a space in between.
if ((int)edit_submode_highl < (int)HLF_COUNT) {
- sub_attr = hl_attr(edit_submode_highl);
+ sub_attr = win_hl_attr(curwin, edit_submode_highl);
} else {
sub_attr = attr;
}
@@ -6746,16 +6689,20 @@ int showmode(void)
if (p_ri)
MSG_PUTS_ATTR(_(" REVERSE"), attr);
MSG_PUTS_ATTR(_(" INSERT"), attr);
- } else if (restart_edit == 'I')
+ } else if (restart_edit == 'I' || restart_edit == 'i'
+ || restart_edit == 'a') {
MSG_PUTS_ATTR(_(" (insert)"), attr);
- else if (restart_edit == 'R')
+ } else if (restart_edit == 'R') {
MSG_PUTS_ATTR(_(" (replace)"), attr);
- else if (restart_edit == 'V')
+ } else if (restart_edit == 'V') {
MSG_PUTS_ATTR(_(" (vreplace)"), attr);
- if (p_hkmap)
+ }
+ if (p_hkmap) {
MSG_PUTS_ATTR(_(" Hebrew"), attr);
- if (p_fkmap)
+ }
+ if (p_fkmap) {
MSG_PUTS_ATTR(farsi_text_5, attr);
+ }
if (State & LANGMAP) {
if (curwin->w_p_arab) {
MSG_PUTS_ATTR(_(" Arabic"), attr);
@@ -6881,7 +6828,6 @@ static void draw_tabline(void)
int modified;
int c;
int len;
- int attr_sel = hl_attr(HLF_TPS);
int attr_nosel = hl_attr(HLF_TP);
int attr_fill = hl_attr(HLF_TPF);
char_u *p;
@@ -6894,6 +6840,10 @@ static void draw_tabline(void)
}
redraw_tabline = false;
+ if (ui_is_external(kUITabline)) {
+ ui_ext_tabline_update();
+ return;
+ }
if (tabline_height() < 1)
return;
@@ -6939,16 +6889,6 @@ static void draw_tabline(void)
scol = col;
- if (tp->tp_topframe == topframe)
- attr = attr_sel;
- if (use_sep_chars && col > 0)
- screen_putchar('|', 0, col++, attr);
-
- if (tp->tp_topframe != topframe)
- attr = attr_nosel;
-
- screen_putchar(' ', 0, col++, attr);
-
if (tp == curtab) {
cwp = curwin;
wp = firstwin;
@@ -6957,10 +6897,29 @@ static void draw_tabline(void)
wp = tp->tp_firstwin;
}
- modified = FALSE;
- for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount)
- if (bufIsChanged(wp->w_buffer))
- modified = TRUE;
+
+ if (tp->tp_topframe == topframe) {
+ attr = win_hl_attr(cwp, HLF_TPS);
+ }
+ if (use_sep_chars && col > 0) {
+ screen_putchar('|', 0, col++, attr);
+ }
+
+ if (tp->tp_topframe != topframe) {
+ attr = win_hl_attr(cwp, HLF_TP);
+ }
+
+ screen_putchar(' ', 0, col++, attr);
+
+ modified = false;
+
+ for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount) {
+ if (bufIsChanged(wp->w_buffer)) {
+ modified = true;
+ }
+ }
+
+
if (modified || wincount > 1) {
if (wincount > 1) {
vim_snprintf((char *)NameBuff, MAXPATHL, "%d", wincount);
@@ -6968,7 +6927,7 @@ static void draw_tabline(void)
if (col + len >= Columns - 3)
break;
screen_puts_len(NameBuff, len, 0, col,
- hl_combine_attr(attr, hl_attr(HLF_T)));
+ hl_combine_attr(attr, win_hl_attr(cwp, HLF_T)));
col += len;
}
if (modified)
@@ -7034,6 +6993,22 @@ static void draw_tabline(void)
redraw_tabline = FALSE;
}
+void ui_ext_tabline_update(void)
+{
+ Array tabs = ARRAY_DICT_INIT;
+ FOR_ALL_TABS(tp) {
+ Dictionary tab_info = ARRAY_DICT_INIT;
+ PUT(tab_info, "tab", TABPAGE_OBJ(tp->handle));
+
+ win_T *cwp = (tp == curtab) ? curwin : tp->tp_curwin;
+ get_trans_bufname(cwp->w_buffer);
+ PUT(tab_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff)));
+
+ ADD(tabs, DICTIONARY_OBJ(tab_info));
+ }
+ ui_call_tabline_update(curtab->handle, tabs);
+}
+
/*
* Get buffer name for "buf" into NameBuff[].
* Takes care of special buffer names and translates special characters.
@@ -7050,25 +7025,28 @@ void get_trans_bufname(buf_T *buf)
/*
* Get the character to use in a status line. Get its attributes in "*attr".
*/
-static int fillchar_status(int *attr, int is_curwin)
+static int fillchar_status(int *attr, win_T *wp)
{
int fill;
+ bool is_curwin = (wp == curwin);
if (is_curwin) {
- *attr = hl_attr(HLF_S);
+ *attr = win_hl_attr(wp, HLF_S);
fill = fill_stl;
} else {
- *attr = hl_attr(HLF_SNC);
+ *attr = win_hl_attr(wp, HLF_SNC);
fill = fill_stlnc;
}
/* Use fill when there is highlighting, and highlighting of current
* window differs, or the fillchars differ, or this is not the
* current window */
- if (*attr != 0 && ((hl_attr(HLF_S) != hl_attr(HLF_SNC)
- || !is_curwin || firstwin == lastwin)
- || (fill_stl != fill_stlnc)))
+ if (*attr != 0 && ((win_hl_attr(wp, HLF_S) != win_hl_attr(wp, HLF_SNC)
+ || !is_curwin || ONE_WINDOW)
+ || (fill_stl != fill_stlnc))) {
return fill;
- if (is_curwin)
+ }
+ if (is_curwin) {
return '^';
+ }
return '=';
}
@@ -7076,13 +7054,10 @@ static int fillchar_status(int *attr, int is_curwin)
* Get the character to use in a separator between vertically split windows.
* Get its attributes in "*attr".
*/
-static int fillchar_vsep(int *attr)
+static int fillchar_vsep(win_T *wp, int *attr)
{
- *attr = hl_attr(HLF_C);
- if (*attr == 0 && fill_vert == ' ')
- return '|';
- else
- return fill_vert;
+ *attr = win_hl_attr(wp, HLF_C);
+ return fill_vert;
}
/*
@@ -7197,7 +7172,7 @@ static void win_redr_ruler(win_T *wp, int always)
if (wp->w_status_height) {
row = wp->w_winrow + wp->w_height;
- fillchar = fillchar_status(&attr, wp == curwin);
+ fillchar = fillchar_status(&attr, wp);
off = wp->w_wincol;
width = wp->w_width;
} else {
@@ -7324,13 +7299,7 @@ int number_width(win_T *wp)
return n;
}
-/*
- * Set size of the Vim shell.
- * If 'mustset' is TRUE, we must set Rows and Columns, do not get the real
- * window size (this is used for the :win command).
- * If 'mustset' is FALSE, we may try to get the real window size and if
- * it fails use 'width' and 'height'.
- */
+/// Set dimensions of the Nvim application "shell".
void screen_resize(int width, int height)
{
static int busy = FALSE;
@@ -7415,8 +7384,8 @@ void screen_resize(int width, int height)
--busy;
}
-// Check if the new shell size is valid, correct it if it's too small or way
-// too big.
+/// Check if the new Nvim application "shell" dimensions are valid.
+/// Correct it if it's too small or way too big.
void check_shellsize(void)
{
if (Rows < min_rows()) {