mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 9.0.1578: SpellCap highlight not always updated when needed
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 #12428, closes #12420)
This commit is contained in:
committed by
Bram Moolenaar
parent
1271572a35
commit
2ac6497f0e
@@ -1062,7 +1062,7 @@ win_line(
|
||||
linenr_T lnum,
|
||||
int startrow,
|
||||
int endrow,
|
||||
int nochange UNUSED, // not updating for changed text
|
||||
int mod_top UNUSED, // top line updated for changed text
|
||||
int number_only) // only update the number column
|
||||
{
|
||||
winlinevars_T wlv; // variables passed between functions
|
||||
@@ -1314,11 +1314,18 @@ win_line(
|
||||
|
||||
// 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
|
||||
#ifdef FEAT_FOLDING
|
||||
|| hasFoldingWin(wp, lnum - 1, NULL, NULL, TRUE, NULL)
|
||||
#endif
|
||||
) && check_need_cap(wp, lnum, 0)))
|
||||
cap_col = 0;
|
||||
else if (lnum != capcol_lnum)
|
||||
cap_col = -1;
|
||||
capcol_lnum = 0;
|
||||
}
|
||||
#endif
|
||||
@@ -2787,7 +2794,7 @@ win_line(
|
||||
p = prev_ptr;
|
||||
cap_col -= (int)(prev_ptr - line);
|
||||
len = spell_check(wp, p, &spell_hlf, &cap_col,
|
||||
nochange);
|
||||
mod_top == 0);
|
||||
word_end = v + len;
|
||||
|
||||
// In Insert mode only highlight a word that
|
||||
|
@@ -2487,8 +2487,7 @@ win_update(win_T *wp)
|
||||
#endif
|
||||
|
||||
// Display one line.
|
||||
row = win_line(wp, lnum, srow, wp->w_height,
|
||||
mod_top == 0, FALSE);
|
||||
row = win_line(wp, lnum, srow, wp->w_height, mod_top, FALSE);
|
||||
|
||||
#ifdef FEAT_FOLDING
|
||||
wp->w_lines[idx].wl_folded = FALSE;
|
||||
@@ -2535,7 +2534,7 @@ win_update(win_T *wp)
|
||||
fold_line(wp, fold_count, &win_foldinfo, lnum, row);
|
||||
else
|
||||
#endif
|
||||
(void)win_line(wp, lnum, srow, wp->w_height, TRUE, TRUE);
|
||||
(void)win_line(wp, lnum, srow, wp->w_height, mod_top, TRUE);
|
||||
}
|
||||
|
||||
// This line does not need to be drawn, advance to the next one.
|
||||
|
@@ -28,7 +28,7 @@ void init_spell_chartab(void);
|
||||
int spell_iswordp(char_u *p, win_T *wp);
|
||||
int spell_iswordp_nmw(char_u *p, win_T *wp);
|
||||
int spell_casefold(win_T *wp, char_u *str, int len, char_u *buf, int buflen);
|
||||
int check_need_cap(linenr_T lnum, colnr_T col);
|
||||
int check_need_cap(win_T *wp, linenr_T lnum, colnr_T col);
|
||||
void ex_spellrepall(exarg_T *eap);
|
||||
void onecap_copy(char_u *word, char_u *wcopy, int upper);
|
||||
void allcap_copy(char_u *word, char_u *wcopy);
|
||||
|
40
src/spell.c
40
src/spell.c
@@ -1342,7 +1342,7 @@ spell_move_to(
|
||||
{
|
||||
// For spellbadword(): check if first word needs a capital.
|
||||
col = getwhitecols(line);
|
||||
if (check_need_cap(lnum, col))
|
||||
if (check_need_cap(curwin, lnum, col))
|
||||
capcol = col;
|
||||
|
||||
// Need to get the line again, may have looked at the previous
|
||||
@@ -2815,24 +2815,20 @@ spell_casefold(
|
||||
|
||||
/*
|
||||
* Check if the word at line "lnum" column "col" is required to start with a
|
||||
* capital. This uses 'spellcapcheck' of the current buffer.
|
||||
* capital. This uses 'spellcapcheck' of the buffer in window "wp".
|
||||
*/
|
||||
int
|
||||
check_need_cap(linenr_T lnum, colnr_T col)
|
||||
check_need_cap(win_T *wp, linenr_T lnum, colnr_T col)
|
||||
{
|
||||
int need_cap = FALSE;
|
||||
char_u *line;
|
||||
char_u *line_copy = NULL;
|
||||
char_u *p;
|
||||
colnr_T endcol;
|
||||
regmatch_T regmatch;
|
||||
|
||||
if (curwin->w_s->b_cap_prog == NULL)
|
||||
if (wp->w_s->b_cap_prog == NULL)
|
||||
return FALSE;
|
||||
|
||||
line = ml_get_curline();
|
||||
endcol = 0;
|
||||
if (getwhitecols(line) >= (int)col)
|
||||
int need_cap = FALSE;
|
||||
char_u *line = col ? ml_get_buf(wp->w_buffer, lnum, FALSE) : NULL;
|
||||
char_u *line_copy = NULL;
|
||||
colnr_T endcol = 0;
|
||||
|
||||
if (col == 0 || getwhitecols(line) >= col)
|
||||
{
|
||||
// At start of line, check if previous line is empty or sentence
|
||||
// ends there.
|
||||
@@ -2840,13 +2836,16 @@ check_need_cap(linenr_T lnum, colnr_T col)
|
||||
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
|
||||
{
|
||||
// Append a space in place of the line break.
|
||||
line_copy = concat_str(line, (char_u *)" ");
|
||||
if (line_copy == NULL)
|
||||
return FALSE;
|
||||
|
||||
line = line_copy;
|
||||
endcol = (colnr_T)STRLEN(line);
|
||||
}
|
||||
@@ -2858,13 +2857,14 @@ check_need_cap(linenr_T lnum, colnr_T col)
|
||||
if (endcol > 0)
|
||||
{
|
||||
// Check if sentence ends before the bad word.
|
||||
regmatch.regprog = curwin->w_s->b_cap_prog;
|
||||
regmatch_T regmatch;
|
||||
regmatch.regprog = wp->w_s->b_cap_prog;
|
||||
regmatch.rm_ic = FALSE;
|
||||
p = line + endcol;
|
||||
char_u *p = line + endcol;
|
||||
for (;;)
|
||||
{
|
||||
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(®match, p, 0)
|
||||
&& regmatch.endp[0] == line + endcol)
|
||||
@@ -2873,7 +2873,7 @@ 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;
|
||||
}
|
||||
|
||||
vim_free(line_copy);
|
||||
@@ -4340,7 +4340,7 @@ static int 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -538,7 +538,8 @@ spell_suggest(int count)
|
||||
// Get the word and its length.
|
||||
|
||||
// Figure out if the word should be capitalised.
|
||||
need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col);
|
||||
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 = vim_strsave(ml_get_curline());
|
||||
|
8
src/testdir/dumps/Test_spell_6.dump
Normal file
8
src/testdir/dumps/Test_spell_6.dump
Normal file
@@ -0,0 +1,8 @@
|
||||
| +0&#ffffff0@2|T|h|i|s| |l|i|n|e| |h|a|s| |a| |s+0&#ffd7d7255|e|p|l@1| +0&#ffffff0|e|r@1|o|r|.| |a+0fd7ff255|n|d| +0&#ffffff0|m|i|s@1|i|n|g| |c|a|p|s| |a|n|d| |t|r|a|i|l|i|n|g| |s|p|a|c|e|s|.| @5
|
||||
|a+0fd7ff255|n|o|t|h|e|r| +0&#ffffff0|m|i|s@1|i|n|g| |c|a|p| |h|e|r|e|.| @49
|
||||
|N|o|t| @71
|
||||
>++0#0000e05#a8a8a8255|-@1| @1|2| |l|i|n|e|s|:| |a|n|d| |h|e|r|e|.|-@51
|
||||
|a+0#0000000#5fd7ff255|n|d| +0&#ffffff0|h|e|r|e|.| @65
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @73
|
||||
| +0#0000000&@56|4|,|4|-|1| @8|A|l@1|
|
8
src/testdir/dumps/Test_spell_7.dump
Normal file
8
src/testdir/dumps/Test_spell_7.dump
Normal file
@@ -0,0 +1,8 @@
|
||||
| +0&#ffffff0@2|T|h|i|s| |l|i|n|e| |h|a|s| |a| |s+0&#ffd7d7255|e|p|l@1| +0&#ffffff0|e|r@1|o|r|.| |a+0fd7ff255|n|d| +0&#ffffff0|m|i|s@1|i|n|g| |c|a|p|s| |a|n|d| |t|r|a|i|l|i|n|g| |s|p|a|c|e|s|.| @5
|
||||
|a+0fd7ff255|n|o|t|h|e|r| +0&#ffffff0|m|i|s@1|i|n|g| |c|a|p| |h|e|r>e| @50
|
||||
|++0#0000e05#a8a8a8255|-@1| @1|2| |l|i|n|e|s|:| |N|o|t|-@57
|
||||
|a+0#0000000#5fd7ff255|n|d| +0&#ffffff0|h|e|r|e|.| @65
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
| +0#0000000&@56|2|,|2|4| @9|A|l@1|
|
8
src/testdir/dumps/Test_spell_8.dump
Normal file
8
src/testdir/dumps/Test_spell_8.dump
Normal file
@@ -0,0 +1,8 @@
|
||||
|a+0fd7ff255|n|o|t|h|e|r| +0&#ffffff0|m|i|s@1|i|n|g| |c|a|p| |h|e|r|e| @50
|
||||
|++0#0000e05#a8a8a8255|-@1| @1|2| |l|i|n|e|s|:| |N|o|t|-@57
|
||||
|a+0#0000000#5fd7ff255|n|d| +0&#ffffff0|h|e|r|e>.| @65
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
| +0#0000000&@56|5|,|9| @10|B|o|t|
|
@@ -999,13 +999,26 @@ func Test_spell_screendump_spellcap()
|
||||
call VerifyScreenDump(buf, 'Test_spell_3', {})
|
||||
|
||||
" Deleting a full stop removes missing Cap in next line
|
||||
call term_sendkeys(buf, "5Gddk$x")
|
||||
call term_sendkeys(buf, "5Gdd\<C-L>k$x")
|
||||
call VerifyScreenDump(buf, 'Test_spell_4', {})
|
||||
|
||||
" Undo also updates the next line (go to command line to remove message)
|
||||
call term_sendkeys(buf, "u:\<Esc>")
|
||||
call VerifyScreenDump(buf, 'Test_spell_5', {})
|
||||
|
||||
" Folding an empty line does not remove Cap in next line
|
||||
call term_sendkeys(buf, "uzfk:\<Esc>")
|
||||
call VerifyScreenDump(buf, 'Test_spell_6', {})
|
||||
|
||||
" Folding the end of a sentence does not remove Cap in next line
|
||||
" and editing a line does not remove Cap in current line
|
||||
call term_sendkeys(buf, "Jzfkk$x")
|
||||
call VerifyScreenDump(buf, 'Test_spell_7', {})
|
||||
|
||||
" Cap is correctly applied in the first row of a window
|
||||
call term_sendkeys(buf, "\<C-E>\<C-L>")
|
||||
call VerifyScreenDump(buf, 'Test_spell_8', {})
|
||||
|
||||
" clean up
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1578,
|
||||
/**/
|
||||
1577,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user