mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.0.1585: weird use of static variables for spell checking
Problem: Weird use of static variables for spell checking. Solution: Move the variables to a structure and pass them from win_update() to win_line(). (Luuk van Baal, closes #12448)
This commit is contained in:
committed by
Bram Moolenaar
parent
1ba0b9e36f
commit
30805a1aba
135
src/drawline.c
135
src/drawline.c
@@ -1050,8 +1050,11 @@ apply_cursorline_highlight(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display line "lnum" of window 'wp' on the screen.
|
* Display line "lnum" of window "wp" on the screen.
|
||||||
* Start at row "startrow", stop when "endrow" is reached.
|
* Start at row "startrow", stop when "endrow" is reached.
|
||||||
|
* When "number_only" is TRUE only update the number column.
|
||||||
|
* "spv" is used to store information for spell checking, kept between
|
||||||
|
* sequential calls for the same window.
|
||||||
* wp->w_virtcol needs to be valid.
|
* wp->w_virtcol needs to be valid.
|
||||||
*
|
*
|
||||||
* Return the number of last row the line occupies.
|
* Return the number of last row the line occupies.
|
||||||
@@ -1062,8 +1065,8 @@ win_line(
|
|||||||
linenr_T lnum,
|
linenr_T lnum,
|
||||||
int startrow,
|
int startrow,
|
||||||
int endrow,
|
int endrow,
|
||||||
int mod_top UNUSED, // top line updated for changed text
|
int number_only,
|
||||||
int number_only) // only update the number column
|
spellvars_T *spv UNUSED)
|
||||||
{
|
{
|
||||||
winlinevars_T wlv; // variables passed between functions
|
winlinevars_T wlv; // variables passed between functions
|
||||||
|
|
||||||
@@ -1139,7 +1142,6 @@ win_line(
|
|||||||
int reset_extra_attr = FALSE;
|
int reset_extra_attr = FALSE;
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_SPELL
|
#ifdef FEAT_SPELL
|
||||||
int has_spell = FALSE; // this buffer has spell checking
|
|
||||||
int can_spell = FALSE;
|
int can_spell = FALSE;
|
||||||
# define SPWORDLEN 150
|
# define SPWORDLEN 150
|
||||||
char_u nextline[SPWORDLEN * 2];// text with start of the next line
|
char_u nextline[SPWORDLEN * 2];// text with start of the next line
|
||||||
@@ -1148,11 +1150,6 @@ win_line(
|
|||||||
// starts
|
// starts
|
||||||
int spell_attr = 0; // attributes desired by spelling
|
int spell_attr = 0; // attributes desired by spelling
|
||||||
int word_end = 0; // last byte with same spell_attr
|
int word_end = 0; // last byte with same spell_attr
|
||||||
static linenr_T checked_lnum = 0; // line number for "checked_col"
|
|
||||||
static int checked_col = 0; // column in "checked_lnum" up to which
|
|
||||||
// there are no spell errors
|
|
||||||
static int cap_col = -1; // column to check for Cap word
|
|
||||||
static linenr_T capcol_lnum = 0; // line number where "cap_col" used
|
|
||||||
int cur_checked_col = 0; // checked column for current line
|
int cur_checked_col = 0; // checked column for current line
|
||||||
#endif
|
#endif
|
||||||
int extra_check = 0; // has extra highlighting
|
int extra_check = 0; // has extra highlighting
|
||||||
@@ -1289,47 +1286,6 @@ win_line(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_SPELL
|
|
||||||
if (spell_check_window(wp))
|
|
||||||
{
|
|
||||||
// Prepare for spell checking.
|
|
||||||
has_spell = TRUE;
|
|
||||||
extra_check = TRUE;
|
|
||||||
|
|
||||||
// Get the start of the next line, so that words that wrap to the
|
|
||||||
// next line are found too: "et<line-break>al.".
|
|
||||||
// Trick: skip a few chars for C/shell/Vim comments
|
|
||||||
nextline[SPWORDLEN] = NUL;
|
|
||||||
if (lnum < wp->w_buffer->b_ml.ml_line_count)
|
|
||||||
{
|
|
||||||
line = ml_get_buf(wp->w_buffer, lnum + 1, FALSE);
|
|
||||||
spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When a word wrapped from the previous line the start of the
|
|
||||||
// current line is valid.
|
|
||||||
if (lnum == checked_lnum)
|
|
||||||
cur_checked_col = checked_col;
|
|
||||||
checked_lnum = 0;
|
|
||||||
|
|
||||||
// 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. 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
|
|
||||||
|
|
||||||
// handle Visual active in this window
|
// handle Visual active in this window
|
||||||
if (VIsual_active && wp->w_buffer == curwin->w_buffer)
|
if (VIsual_active && wp->w_buffer == curwin->w_buffer)
|
||||||
{
|
{
|
||||||
@@ -1497,15 +1453,38 @@ win_line(
|
|||||||
ptr = line;
|
ptr = line;
|
||||||
|
|
||||||
#ifdef FEAT_SPELL
|
#ifdef FEAT_SPELL
|
||||||
if (has_spell && !number_only)
|
if (spv->spv_has_spell && !number_only)
|
||||||
{
|
{
|
||||||
// For checking first word with a capital skip white space.
|
// Prepare for spell checking.
|
||||||
if (cap_col == 0)
|
extra_check = TRUE;
|
||||||
cap_col = getwhitecols(line);
|
|
||||||
|
|
||||||
// To be able to spell-check over line boundaries copy the end of the
|
// When a word wrapped from the previous line the start of the
|
||||||
// current line into nextline[]. Above the start of the next line was
|
// current line is valid.
|
||||||
// copied to nextline[SPWORDLEN].
|
if (lnum == spv->spv_checked_lnum)
|
||||||
|
cur_checked_col = spv->spv_checked_col;
|
||||||
|
if (lnum != spv->spv_capcol_lnum)
|
||||||
|
spv->spv_cap_col = -1;
|
||||||
|
spv->spv_checked_lnum = 0;
|
||||||
|
|
||||||
|
// For checking first word with a capital skip white space.
|
||||||
|
if (spv->spv_cap_col == 0)
|
||||||
|
spv->spv_cap_col = getwhitecols(line);
|
||||||
|
// If current line is empty, check first word in next line for capital.
|
||||||
|
else if (*skipwhite(line) == NUL)
|
||||||
|
{
|
||||||
|
spv->spv_cap_col = 0;
|
||||||
|
spv->spv_capcol_lnum = lnum + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get the start of the next line, so that words that wrap to the
|
||||||
|
// next line are found too: "et<line-break>al.".
|
||||||
|
// Trick: skip a few chars for C/shell/Vim comments
|
||||||
|
nextline[SPWORDLEN] = NUL;
|
||||||
|
if (lnum < wp->w_buffer->b_ml.ml_line_count)
|
||||||
|
spell_cat_line(nextline + SPWORDLEN,
|
||||||
|
ml_get_buf(wp->w_buffer, lnum + 1, FALSE), SPWORDLEN);
|
||||||
|
// Copy the end of the current line into nextline[].
|
||||||
if (nextline[SPWORDLEN] == NUL)
|
if (nextline[SPWORDLEN] == NUL)
|
||||||
{
|
{
|
||||||
// No next line or it is empty.
|
// No next line or it is empty.
|
||||||
@@ -1723,7 +1702,7 @@ win_line(
|
|||||||
#ifdef FEAT_SPELL
|
#ifdef FEAT_SPELL
|
||||||
// When spell checking a word we need to figure out the start of the
|
// When spell checking a word we need to figure out the start of the
|
||||||
// word and if it's badly spelled or not.
|
// word and if it's badly spelled or not.
|
||||||
if (has_spell)
|
if (spv->spv_has_spell)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
colnr_T linecol = (colnr_T)(ptr - line);
|
colnr_T linecol = (colnr_T)(ptr - line);
|
||||||
@@ -2327,9 +2306,9 @@ win_line(
|
|||||||
# endif
|
# endif
|
||||||
syntax_attr = get_syntax_attr((colnr_T)v,
|
syntax_attr = get_syntax_attr((colnr_T)v,
|
||||||
# ifdef FEAT_SPELL
|
# ifdef FEAT_SPELL
|
||||||
has_spell ? &can_spell :
|
spv->spv_has_spell ? &can_spell :
|
||||||
# endif
|
# endif
|
||||||
NULL, FALSE);
|
NULL, FALSE);
|
||||||
prev_syntax_col = v;
|
prev_syntax_col = v;
|
||||||
prev_syntax_attr = syntax_attr;
|
prev_syntax_attr = syntax_attr;
|
||||||
}
|
}
|
||||||
@@ -2768,7 +2747,7 @@ win_line(
|
|||||||
// @Spell cluster is not used or the current syntax item
|
// @Spell cluster is not used or the current syntax item
|
||||||
// contains the @Spell cluster.
|
// contains the @Spell cluster.
|
||||||
v = (long)(ptr - line);
|
v = (long)(ptr - line);
|
||||||
if (has_spell && v >= word_end && v > cur_checked_col)
|
if (spv->spv_has_spell && v >= word_end && v > cur_checked_col)
|
||||||
{
|
{
|
||||||
spell_attr = 0;
|
spell_attr = 0;
|
||||||
// do not calculate cap_col at the end of the line or when
|
// do not calculate cap_col at the end of the line or when
|
||||||
@@ -2792,9 +2771,9 @@ win_line(
|
|||||||
p = nextline + (prev_ptr - line) - nextlinecol;
|
p = nextline + (prev_ptr - line) - nextlinecol;
|
||||||
else
|
else
|
||||||
p = prev_ptr;
|
p = prev_ptr;
|
||||||
cap_col -= (int)(prev_ptr - line);
|
spv->spv_cap_col -= (int)(prev_ptr - line);
|
||||||
len = spell_check(wp, p, &spell_hlf, &cap_col,
|
len = spell_check(wp, p, &spell_hlf, &spv->spv_cap_col,
|
||||||
mod_top == 0);
|
spv->spv_unchanged);
|
||||||
word_end = v + len;
|
word_end = v + len;
|
||||||
|
|
||||||
// In Insert mode only highlight a word that
|
// In Insert mode only highlight a word that
|
||||||
@@ -2815,29 +2794,30 @@ win_line(
|
|||||||
{
|
{
|
||||||
// Remember that the good word continues at the
|
// Remember that the good word continues at the
|
||||||
// start of the next line.
|
// start of the next line.
|
||||||
checked_lnum = lnum + 1;
|
spv->spv_checked_lnum = lnum + 1;
|
||||||
checked_col = (int)((p - nextline)
|
spv->spv_checked_col = (p - nextline) + len
|
||||||
+ len - nextline_idx);
|
- nextline_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn index into actual attributes.
|
// Turn index into actual attributes.
|
||||||
if (spell_hlf != HLF_COUNT)
|
if (spell_hlf != HLF_COUNT)
|
||||||
spell_attr = highlight_attr[spell_hlf];
|
spell_attr = highlight_attr[spell_hlf];
|
||||||
|
|
||||||
if (cap_col > 0)
|
if (spv->spv_cap_col > 0)
|
||||||
{
|
{
|
||||||
if (p != prev_ptr
|
if (p != prev_ptr
|
||||||
&& (p - nextline) + cap_col >= nextline_idx)
|
&& (p - nextline) + spv->spv_cap_col
|
||||||
|
>= nextline_idx)
|
||||||
{
|
{
|
||||||
// Remember that the word in the next line
|
// Remember that the word in the next line
|
||||||
// must start with a capital.
|
// must start with a capital.
|
||||||
capcol_lnum = lnum + 1;
|
spv->spv_capcol_lnum = lnum + 1;
|
||||||
cap_col = (int)((p - nextline) + cap_col
|
spv->spv_cap_col = ((p - nextline)
|
||||||
- nextline_idx);
|
+ spv->spv_cap_col - nextline_idx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// Compute the actual column.
|
// Compute the actual column.
|
||||||
cap_col += (int)(prev_ptr - line);
|
spv->spv_cap_col += (prev_ptr - line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4119,15 +4099,6 @@ win_line(
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // for every character in the line
|
} // for every character in the line
|
||||||
|
|
||||||
#ifdef FEAT_SPELL
|
|
||||||
// After an empty line check first word for capital.
|
|
||||||
if (*skipwhite(line) == NUL)
|
|
||||||
{
|
|
||||||
capcol_lnum = lnum + 1;
|
|
||||||
cap_col = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
vim_free(text_props);
|
vim_free(text_props);
|
||||||
vim_free(text_prop_idxs);
|
vim_free(text_prop_idxs);
|
||||||
|
@@ -2191,11 +2191,25 @@ win_update(win_T *wp)
|
|||||||
redraw_win_toolbar(wp);
|
redraw_win_toolbar(wp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
lnum = wp->w_topline; // first line shown in window
|
||||||
|
|
||||||
|
spellvars_T spv;
|
||||||
|
#ifdef FEAT_SPELL
|
||||||
|
// Initialize spell related variables for the first drawn line.
|
||||||
|
CLEAR_FIELD(spv);
|
||||||
|
spv.spv_has_spell = spell_check_window(wp);
|
||||||
|
if (spv.spv_has_spell)
|
||||||
|
{
|
||||||
|
spv.spv_unchanged = mod_top == 0;
|
||||||
|
spv.spv_capcol_lnum = mod_top ? mod_top : lnum;
|
||||||
|
spv.spv_cap_col = check_need_cap(wp, spv.spv_capcol_lnum, 0) ? 0 : - 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Update all the window rows.
|
// Update all the window rows.
|
||||||
idx = 0; // first entry in w_lines[].wl_size
|
idx = 0; // first entry in w_lines[].wl_size
|
||||||
row = 0;
|
row = 0;
|
||||||
srow = 0;
|
srow = 0;
|
||||||
lnum = wp->w_topline; // first line shown in window
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
// stop updating when reached the end of the window (check for _past_
|
// stop updating when reached the end of the window (check for _past_
|
||||||
@@ -2450,10 +2464,19 @@ win_update(win_T *wp)
|
|||||||
fold_line(wp, fold_count, &win_foldinfo, lnum, row);
|
fold_line(wp, fold_count, &win_foldinfo, lnum, row);
|
||||||
++row;
|
++row;
|
||||||
--fold_count;
|
--fold_count;
|
||||||
|
linenr_T lnume = lnum + fold_count;
|
||||||
wp->w_lines[idx].wl_folded = TRUE;
|
wp->w_lines[idx].wl_folded = TRUE;
|
||||||
wp->w_lines[idx].wl_lastlnum = lnum + fold_count;
|
wp->w_lines[idx].wl_lastlnum = lnume;
|
||||||
# ifdef FEAT_SYN_HL
|
# ifdef FEAT_SYN_HL
|
||||||
did_update = DID_FOLD;
|
did_update = DID_FOLD;
|
||||||
|
# endif
|
||||||
|
# ifdef FEAT_SPELL
|
||||||
|
// Check if the line after this fold requires a capital.
|
||||||
|
if (spv.spv_has_spell && check_need_cap(wp, lnume + 1, 0))
|
||||||
|
{
|
||||||
|
spv.spv_cap_col = 0;
|
||||||
|
spv.spv_capcol_lnum = lnume + 1;
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2487,7 +2510,7 @@ win_update(win_T *wp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Display one line.
|
// Display one line.
|
||||||
row = win_line(wp, lnum, srow, wp->w_height, mod_top, FALSE);
|
row = win_line(wp, lnum, srow, wp->w_height, FALSE, &spv);
|
||||||
|
|
||||||
#ifdef FEAT_FOLDING
|
#ifdef FEAT_FOLDING
|
||||||
wp->w_lines[idx].wl_folded = FALSE;
|
wp->w_lines[idx].wl_folded = FALSE;
|
||||||
@@ -2534,7 +2557,7 @@ win_update(win_T *wp)
|
|||||||
fold_line(wp, fold_count, &win_foldinfo, lnum, row);
|
fold_line(wp, fold_count, &win_foldinfo, lnum, row);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
(void)win_line(wp, lnum, srow, wp->w_height, mod_top, TRUE);
|
(void)win_line(wp, lnum, srow, wp->w_height, TRUE, &spv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This line does not need to be drawn, advance to the next one.
|
// This line does not need to be drawn, advance to the next one.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* drawline.c */
|
/* drawline.c */
|
||||||
int text_prop_position(win_T *wp, textprop_T *tp, int vcol, int scr_col, int *n_extra, char_u **p_extra, int *n_attr, int *n_attr_skip, int do_skip);
|
int text_prop_position(win_T *wp, textprop_T *tp, int vcol, int scr_col, int *n_extra, char_u **p_extra, int *n_attr, int *n_attr_skip, int do_skip);
|
||||||
int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int nochange, int number_only);
|
int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int number_only, spellvars_T *spv);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -4870,3 +4870,18 @@ typedef struct
|
|||||||
// message (when it is not NULL).
|
// message (when it is not NULL).
|
||||||
char *os_errbuf;
|
char *os_errbuf;
|
||||||
} optset_T;
|
} optset_T;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Spell checking variables passed from win_update() to win_line().
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int spv_has_spell; // drawn window has spell checking
|
||||||
|
#ifdef FEAT_SPELL
|
||||||
|
int spv_unchanged; // not updating for changed text
|
||||||
|
int spv_checked_col; // column in "checked_lnum" up to
|
||||||
|
// which there are no spell errors
|
||||||
|
linenr_T spv_checked_lnum; // line number for "checked_col"
|
||||||
|
int spv_cap_col; // column to check for Cap word
|
||||||
|
linenr_T spv_capcol_lnum; // line number for "cap_col"
|
||||||
|
#endif
|
||||||
|
} spellvars_T;
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1585,
|
||||||
/**/
|
/**/
|
||||||
1584,
|
1584,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user