summaryrefslogtreecommitdiffstats
path: root/src/drawline.c
diff options
context:
space:
mode:
authorLuuk van Baal <luukvbaal@gmail.com>2023-05-27 22:22:10 +0100
committerBram Moolenaar <Bram@vim.org>2023-05-27 22:22:10 +0100
commit30805a1aba0067cf0087f9a0e5c184562433e2e7 (patch)
treefb230c3a843711b3cb0369ef275f3377a8154c09 /src/drawline.c
parent1ba0b9e36f36926a7675b31efeda7d3e495c9157 (diff)
patch 9.0.1585: weird use of static variables for spell checkingv9.0.1585
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)
Diffstat (limited to 'src/drawline.c')
-rw-r--r--src/drawline.c133
1 files changed, 52 insertions, 81 deletions
diff --git a/src/drawline.c b/src/drawline.c
index 3791ece432..3811060df1 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -1050,8 +1050,11 @@ apply_cursorline_highlight(
#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.
+ * 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.
*
* Return the number of last row the line occupies.
@@ -1062,8 +1065,8 @@ win_line(
linenr_T lnum,
int startrow,
int endrow,
- int mod_top UNUSED, // top line updated for changed text
- int number_only) // only update the number column
+ int number_only,
+ spellvars_T *spv UNUSED)
{
winlinevars_T wlv; // variables passed between functions
@@ -1139,7 +1142,6 @@ win_line(
int reset_extra_attr = FALSE;
#endif
#ifdef FEAT_SPELL
- int has_spell = FALSE; // this buffer has spell checking
int can_spell = FALSE;
# define SPWORDLEN 150
char_u nextline[SPWORDLEN * 2];// text with start of the next line
@@ -1148,11 +1150,6 @@ win_line(
// starts
int spell_attr = 0; // attributes desired by spelling
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
#endif
int extra_check = 0; // has extra highlighting
@@ -1289,47 +1286,6 @@ win_line(
}
#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
if (VIsual_active && wp->w_buffer == curwin->w_buffer)
{
@@ -1497,15 +1453,38 @@ win_line(
ptr = line;
#ifdef FEAT_SPELL
- if (has_spell && !number_only)
+ if (spv->spv_has_spell && !number_only)
{
+ // Prepare for spell checking.
+ extra_check = TRUE;
+
+ // When a word wrapped from the previous line the start of the
+ // current line is valid.
+ 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 (cap_col == 0)
- cap_col = getwhitecols(line);
+ 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;
+ }
+
- // To be able to spell-check over line boundaries copy the end of the
- // current line into nextline[]. Above the start of the next line was
- // copied to nextline[SPWORDLEN].
+ // 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)
{
// No next line or it is empty.
@@ -1723,7 +1702,7 @@ win_line(
#ifdef FEAT_SPELL
// When spell checking a word we need to figure out the start of the
// word and if it's badly spelled or not.
- if (has_spell)
+ if (spv->spv_has_spell)
{
int len;
colnr_T linecol = (colnr_T)(ptr - line);
@@ -2327,9 +2306,9 @@ win_line(
# endif
syntax_attr = get_syntax_attr((colnr_T)v,
# ifdef FEAT_SPELL
- has_spell ? &can_spell :
+ spv->spv_has_spell ? &can_spell :
# endif
- NULL, FALSE);
+ NULL, FALSE);
prev_syntax_col = v;
prev_syntax_attr = syntax_attr;
}
@@ -2768,7 +2747,7 @@ win_line(
// @Spell cluster is not used or the current syntax item
// contains the @Spell cluster.
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;
// 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;
else
p = prev_ptr;
- cap_col -= (int)(prev_ptr - line);
- len = spell_check(wp, p, &spell_hlf, &cap_col,
- mod_top == 0);
+ spv->spv_cap_col -= (int)(prev_ptr - line);
+ len = spell_check(wp, p, &spell_hlf, &spv->spv_cap_col,
+ spv->spv_unchanged);
word_end = v + len;
// In Insert mode only highlight a word that
@@ -2815,29 +2794,30 @@ win_line(
{
// Remember that the good word continues at the
// start of the next line.
- checked_lnum = lnum + 1;
- checked_col = (int)((p - nextline)
- + len - nextline_idx);
+ spv->spv_checked_lnum = lnum + 1;
+ spv->spv_checked_col = (p - nextline) + len
+ - nextline_idx;
}
// Turn index into actual attributes.
if (spell_hlf != HLF_COUNT)
spell_attr = highlight_attr[spell_hlf];
- if (cap_col > 0)
+ if (spv->spv_cap_col > 0)
{
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
// must start with a capital.
- capcol_lnum = lnum + 1;
- cap_col = (int)((p - nextline) + cap_col
- - nextline_idx);
+ spv->spv_capcol_lnum = lnum + 1;
+ spv->spv_cap_col = ((p - nextline)
+ + spv->spv_cap_col - nextline_idx);
}
else
// 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
-
-#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
vim_free(text_props);
vim_free(text_prop_idxs);