aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
authorluukvbaal <luukvbaal@gmail.com>2023-05-26 02:08:18 +0200
committerGitHub <noreply@github.com>2023-05-26 08:08:18 +0800
commitf733595e795cd2b819cb8fd18327cd51f47b2124 (patch)
tree280a35641132753495e4720ff95b9a7358d75dfe /src/nvim
parentee986ee0449b828ca64bf7d4c69624596aab8319 (diff)
downloadrneovim-f733595e795cd2b819cb8fd18327cd51f47b2124.tar.gz
rneovim-f733595e795cd2b819cb8fd18327cd51f47b2124.tar.bz2
rneovim-f733595e795cd2b819cb8fd18327cd51f47b2124.zip
vim-patch:9.0.1578: SpellCap highlight not always updated when needed (#23755)
Problem: SpellCap highlight not always updated when needed. Solution: Handle updating line below closed fold and other situations where only part of the window is redrawn. (Luuk van Baal, closes vim/vim#12428, closes vim/vim#12420) https://github.com/vim/vim/commit/2ac6497f0ef186f0e3ba67d7f0a485bfb612bb08
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/drawline.c20
-rw-r--r--src/nvim/drawscreen.c9
-rw-r--r--src/nvim/spell.c25
-rw-r--r--src/nvim/spellsuggest.c2
4 files changed, 29 insertions, 27 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index f3332dc8a2..016a25b9d5 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -1028,7 +1028,7 @@ static void win_line_continue(winlinevars_T *wlv)
/// @param lnum line to display
/// @param startrow first row relative to window grid
/// @param endrow last grid row to be redrawn
-/// @param nochange not updating for changed text
+/// @param mod_top top line updated for changed text
/// @param number_only only update the number column
/// @param foldinfo fold info for this line
/// @param[in, out] providers decoration providers active this line
@@ -1036,7 +1036,7 @@ static void win_line_continue(winlinevars_T *wlv)
/// or explicitly return `false`.
///
/// @return the number of last row the line occupies.
-int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, bool number_only,
+int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int mod_top, bool number_only,
foldinfo_T foldinfo, DecorProviders *providers, char **provider_err)
{
winlinevars_T wlv; // variables passed between functions
@@ -1227,12 +1227,16 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// When there was a sentence end in the previous line may require a
// word starting with capital in this line. In line 1 always check
- // the first word.
- if (lnum != capcol_lnum) {
- cap_col = -1;
- }
- if (lnum == 1) {
+ // the first word. Also check for sentence end in the line above
+ // when updating the first row in a window, the top line with
+ // changed text in a window, or if the previous line is folded.
+ if (lnum == 1
+ || ((startrow == 0 || mod_top == lnum
+ || hasFoldingWin(wp, lnum - 1, NULL, NULL, true, NULL))
+ && check_need_cap(wp, lnum, 0))) {
cap_col = 0;
+ } else if (lnum != capcol_lnum) {
+ cap_col = -1;
}
capcol_lnum = 0;
}
@@ -2207,7 +2211,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
p = prev_ptr;
}
cap_col -= (int)(prev_ptr - line);
- size_t tmplen = spell_check(wp, p, &spell_hlf, &cap_col, nochange);
+ size_t tmplen = spell_check(wp, p, &spell_hlf, &cap_col, mod_top == 0);
assert(tmplen <= INT_MAX);
int len = (int)tmplen;
word_end = (int)v + len;
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index 7f7c721379..4f79ba87af 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -2222,9 +2222,8 @@ static void win_update(win_T *wp, DecorProviders *providers)
}
// Display one line
- row = win_line(wp, lnum, srow,
- foldinfo.fi_lines ? srow : wp->w_grid.rows,
- mod_top == 0, false, foldinfo, &line_providers, &provider_err);
+ row = win_line(wp, lnum, srow, foldinfo.fi_lines ? srow : wp->w_grid.rows,
+ mod_top, false, foldinfo, &line_providers, &provider_err);
if (foldinfo.fi_lines == 0) {
wp->w_lines[idx].wl_folded = false;
@@ -2261,7 +2260,7 @@ static void win_update(win_T *wp, DecorProviders *providers)
// text doesn't need to be drawn, but the number column does.
foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum ?
cursorline_fi : fold_info(wp, lnum);
- (void)win_line(wp, lnum, srow, wp->w_grid.rows, true, true,
+ (void)win_line(wp, lnum, srow, wp->w_grid.rows, mod_top, true,
info, &line_providers, &provider_err);
}
@@ -2359,7 +2358,7 @@ static void win_update(win_T *wp, DecorProviders *providers)
// for ml_line_count+1 and only draw filler lines
foldinfo_T info = { 0 };
row = win_line(wp, wp->w_botline, row, wp->w_grid.rows,
- false, false, info, &line_providers, &provider_err);
+ mod_top, false, info, &line_providers, &provider_err);
}
} else if (dollar_vcol == -1) {
wp->w_botline = lnum;
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 498bd56b9e..778266e5ac 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1312,7 +1312,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
} else if (curline && wp == curwin) {
// For spellbadword(): check if first word needs a capital.
col = (colnr_T)getwhitecols(line);
- if (check_need_cap(lnum, col)) {
+ if (check_need_cap(curwin, lnum, col)) {
capcol = col;
}
@@ -2536,25 +2536,24 @@ int spell_casefold(const win_T *wp, char *str, int len, char *buf, int buflen)
}
// Check if the word at line "lnum" column "col" is required to start with a
-// capital. This uses 'spellcapcheck' of the current buffer.
-bool check_need_cap(linenr_T lnum, colnr_T col)
+// capital. This uses 'spellcapcheck' of the buffer in window "wp".
+bool check_need_cap(win_T *wp, linenr_T lnum, colnr_T col)
{
- bool need_cap = false;
-
- if (curwin->w_s->b_cap_prog == NULL) {
+ if (wp->w_s->b_cap_prog == NULL) {
return false;
}
- char *line = get_cursor_line_ptr();
+ bool need_cap = false;
+ char *line = col ? ml_get_buf(wp->w_buffer, lnum, false) : NULL;
char *line_copy = NULL;
colnr_T endcol = 0;
- if (getwhitecols(line) >= (int)col) {
+ if (col == 0 || getwhitecols(line) >= col) {
// At start of line, check if previous line is empty or sentence
// ends there.
if (lnum == 1) {
need_cap = true;
} else {
- line = ml_get(lnum - 1);
+ line = ml_get_buf(wp->w_buffer, lnum - 1, false);
if (*skipwhite(line) == NUL) {
need_cap = true;
} else {
@@ -2571,13 +2570,13 @@ bool check_need_cap(linenr_T lnum, colnr_T col)
if (endcol > 0) {
// Check if sentence ends before the bad word.
regmatch_T regmatch = {
- .regprog = curwin->w_s->b_cap_prog,
+ .regprog = wp->w_s->b_cap_prog,
.rm_ic = false
};
char *p = line + endcol;
while (true) {
MB_PTR_BACK(line, p);
- if (p == line || spell_iswordp_nmw(p, curwin)) {
+ if (p == line || spell_iswordp_nmw(p, wp)) {
break;
}
if (vim_regexec(&regmatch, p, 0)
@@ -2586,7 +2585,7 @@ bool check_need_cap(linenr_T lnum, colnr_T col)
break;
}
}
- curwin->w_s->b_cap_prog = regmatch.regprog;
+ wp->w_s->b_cap_prog = regmatch.regprog;
}
xfree(line_copy);
@@ -3601,7 +3600,7 @@ static bool spell_expand_need_cap;
void spell_expand_check_cap(colnr_T col)
{
- spell_expand_need_cap = check_need_cap(curwin->w_cursor.lnum, col);
+ spell_expand_need_cap = check_need_cap(curwin, curwin->w_cursor.lnum, col);
}
// Get list of spelling suggestions.
diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c
index 84be88be7b..1c34c2487f 100644
--- a/src/nvim/spellsuggest.c
+++ b/src/nvim/spellsuggest.c
@@ -509,7 +509,7 @@ void spell_suggest(int count)
// Get the word and its length.
// Figure out if the word should be capitalised.
- int need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col);
+ int need_cap = check_need_cap(curwin, curwin->w_cursor.lnum, curwin->w_cursor.col);
// Make a copy of current line since autocommands may free the line.
line = xstrdup(get_cursor_line_ptr());