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.c136
1 files changed, 76 insertions, 60 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 3e4d016fe7..50517d2829 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -2592,11 +2592,13 @@ win_line (
shl->startcol = MAXCOL;
shl->endcol = MAXCOL;
shl->attr_cur = 0;
+ shl->is_addpos = false;
v = (long)(ptr - line);
if (cur != NULL) {
cur->pos.cur = 0;
}
- next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
+ next_search_hl(wp, shl, lnum, (colnr_T)v,
+ shl == &search_hl ? NULL : cur);
// Need to get the line again, a multi-line regexp may have made it
// invalid.
@@ -2925,7 +2927,8 @@ win_line (
shl->attr_cur = 0;
prev_syntax_id = 0;
- next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
+ next_search_hl(wp, shl, lnum, (colnr_T)v,
+ shl == &search_hl ? NULL : cur);
pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
/* Need to get the line again, a multi-line regexp
@@ -3760,18 +3763,18 @@ win_line (
if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol)
++prevcol;
- /* Invert at least one char, used for Visual and empty line or
- * highlight match at end of line. If it's beyond the last
- * char on the screen, just overwrite that one (tricky!) Not
- * needed when a '$' was displayed for 'list'. */
- prevcol_hl_flag = FALSE;
- if (prevcol == (long)search_hl.startcol)
- prevcol_hl_flag = TRUE;
- else {
+ // Invert at least one char, used for Visual and empty line or
+ // highlight match at end of line. If it's beyond the last
+ // char on the screen, just overwrite that one (tricky!) Not
+ // needed when a '$' was displayed for 'list'.
+ prevcol_hl_flag = false;
+ if (!search_hl.is_addpos && prevcol == (long)search_hl.startcol) {
+ prevcol_hl_flag = true;
+ } else {
cur = wp->w_match_head;
while (cur != NULL) {
- if (prevcol == (long)cur->hl.startcol) {
- prevcol_hl_flag = TRUE;
+ if (!cur->hl.is_addpos && prevcol == (long)cur->hl.startcol) {
+ prevcol_hl_flag = true;
break;
}
cur = cur->next;
@@ -3821,10 +3824,13 @@ win_line (
shl_flag = TRUE;
} else
shl = &cur->hl;
- if ((ptr - line) - 1 == (long)shl->startcol)
+ if ((ptr - line) - 1 == (long)shl->startcol
+ && (shl == &search_hl || !shl->is_addpos)) {
char_attr = shl->attr;
- if (shl != &search_hl && cur != NULL)
+ }
+ if (shl != &search_hl && cur != NULL) {
cur = cur->next;
+ }
}
}
ScreenAttrs[off] = char_attr;
@@ -4939,8 +4945,8 @@ void win_redr_status(win_T *wp)
*/
static void redraw_custom_statusline(win_T *wp)
{
- static int entered = FALSE;
- int save_called_emsg = called_emsg;
+ static int entered = false;
+ int saved_did_emsg = did_emsg;
/* When called recursively return. This can happen when the statusline
* contains an expression that triggers a redraw. */
@@ -4948,18 +4954,18 @@ static void redraw_custom_statusline(win_T *wp)
return;
entered = TRUE;
- called_emsg = FALSE;
- win_redr_custom(wp, FALSE);
- if (called_emsg) {
- /* When there is an error disable the statusline, otherwise the
- * display is messed up with errors and a redraw triggers the problem
- * again and again. */
+ did_emsg = false;
+ win_redr_custom(wp, false);
+ if (did_emsg) {
+ // When there is an error disable the statusline, otherwise the
+ // display is messed up with errors and a redraw triggers the problem
+ // again and again.
set_string_option_direct((char_u *)"statusline", -1,
(char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
}
- called_emsg |= save_called_emsg;
- entered = FALSE;
+ did_emsg |= saved_did_emsg;
+ entered = false;
}
/*
@@ -5292,7 +5298,7 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
int force_redraw_next = FALSE;
int need_redraw;
- const int l_has_mbyte = has_mbyte;
+ const bool l_has_mbyte = has_mbyte;
const bool l_enc_utf8 = enc_utf8;
const int l_enc_dbcs = enc_dbcs;
@@ -5459,9 +5465,6 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
/* If we detected the next character needs to be redrawn, but the text
* doesn't extend up to there, update the character here. */
if (force_redraw_next && col < screen_Columns) {
- if (l_enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1)
- screen_char_2(off, row, col);
- else
screen_char(off, row, col);
}
}
@@ -5560,8 +5563,9 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
// in progress
n = 0;
while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
- || (cur != NULL && pos_inprogress))) {
- next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n, cur);
+ || (cur != NULL && pos_inprogress))) {
+ next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n,
+ shl == &search_hl ? NULL : cur);
pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
if (shl->lnum != 0) {
shl->first_lnum = shl->lnum
@@ -5694,6 +5698,8 @@ next_search_hl (
}
}
+/// If there is a match fill "shl" and return one.
+/// Return zero otherwise.
static int
next_search_hl_pos(
match_T *shl, // points to a match
@@ -5703,47 +5709,50 @@ next_search_hl_pos(
)
{
int i;
- int bot = -1;
+ int found = -1;
shl->lnum = 0;
for (i = posmatch->cur; i < MAXPOSMATCH; i++) {
- if (posmatch->pos[i].lnum == 0) {
+ llpos_T *pos = &posmatch->pos[i];
+
+ if (pos->lnum == 0) {
break;
}
- if (posmatch->pos[i].col < mincol) {
+ if (pos->len == 0 && pos->col < mincol) {
continue;
}
- if (posmatch->pos[i].lnum == lnum) {
- if (bot != -1) {
- // partially sort positions by column numbers
- // on the same line
- if (posmatch->pos[i].col < posmatch->pos[bot].col) {
- llpos_T tmp = posmatch->pos[i];
+ if (pos->lnum == lnum) {
+ if (found >= 0) {
+ // if this match comes before the one at "found" then swap
+ // them
+ if (pos->col < posmatch->pos[found].col) {
+ llpos_T tmp = *pos;
- posmatch->pos[i] = posmatch->pos[bot];
- posmatch->pos[bot] = tmp;
+ *pos = posmatch->pos[found];
+ posmatch->pos[found] = tmp;
}
} else {
- bot = i;
- shl->lnum = lnum;
+ found = i;
}
}
}
posmatch->cur = 0;
- if (bot != -1) {
- colnr_T start = posmatch->pos[bot].col == 0
- ? 0: posmatch->pos[bot].col - 1;
- colnr_T end = posmatch->pos[bot].col == 0
- ? MAXCOL : start + posmatch->pos[bot].len;
+ if (found >= 0) {
+ colnr_T start = posmatch->pos[found].col == 0
+ ? 0: posmatch->pos[found].col - 1;
+ colnr_T end = posmatch->pos[found].col == 0
+ ? MAXCOL : start + posmatch->pos[found].len;
+ shl->lnum = lnum;
shl->rm.startpos[0].lnum = 0;
shl->rm.startpos[0].col = start;
shl->rm.endpos[0].lnum = 0;
shl->rm.endpos[0].col = end;
- posmatch->cur = bot + 1;
- return true;
+ shl->is_addpos = true;
+ posmatch->cur = found + 1;
+ return 1;
}
- return false;
+ return 0;
}
static void screen_start_highlight(int attr)
@@ -6830,12 +6839,18 @@ void unshowmode(bool force)
if (!redrawing() || (!force && char_avail() && !KeyTyped)) {
redraw_cmdline = true; // delete mode later
} else {
+ clearmode();
+ }
+}
+
+// Clear the mode message.
+void clearmode(void)
+{
msg_pos_mode();
if (Recording) {
recording_mode(hl_attr(HLF_CM));
}
msg_clr_eos();
- }
}
static void recording_mode(int attr)
@@ -6885,16 +6900,17 @@ static void draw_tabline(void)
/* Use the 'tabline' option if it's set. */
if (*p_tal != NUL) {
- int save_called_emsg = called_emsg;
+ int saved_did_emsg = did_emsg;
- /* Check for an error. If there is one we would loop in redrawing the
- * screen. Avoid that by making 'tabline' empty. */
- called_emsg = FALSE;
- win_redr_custom(NULL, FALSE);
- if (called_emsg)
+ // Check for an error. If there is one we would loop in redrawing the
+ // screen. Avoid that by making 'tabline' empty.
+ did_emsg = false;
+ win_redr_custom(NULL, false);
+ if (did_emsg) {
set_string_option_direct((char_u *)"tabline", -1,
- (char_u *)"", OPT_FREE, SID_ERROR);
- called_emsg |= save_called_emsg;
+ (char_u *)"", OPT_FREE, SID_ERROR);
+ }
+ did_emsg |= saved_did_emsg;
} else {
FOR_ALL_TABS(tp) {
++tabcount;