aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/spell.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
commit339e2d15cc26fe86988ea06468d912a46c8d6f29 (patch)
treea6167fc8fcfc6ae2dc102f57b2473858eac34063 /src/nvim/spell.c
parent067dc73729267c0262438a6fdd66e586f8496946 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.gz
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.bz2
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.zip
Merge remote-tracking branch 'upstream/master' into fix_repeatcmdline
Diffstat (limited to 'src/nvim/spell.c')
-rw-r--r--src/nvim/spell.c464
1 files changed, 263 insertions, 201 deletions
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 8e18be5bd1..905f5c25b4 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
// spell.c: code for spell checking
//
// See spellfile.c for the Vim spell file format.
@@ -64,7 +61,7 @@
#include <stdio.h>
#include <string.h>
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
@@ -76,6 +73,7 @@
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
+#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
@@ -83,18 +81,18 @@
#include "nvim/highlight_defs.h"
#include "nvim/insexpand.h"
#include "nvim/log.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
+#include "nvim/option_vars.h"
#include "nvim/os/fs.h"
#include "nvim/os/input.h"
-#include "nvim/os/os_defs.h"
#include "nvim/path.h"
-#include "nvim/pos.h"
+#include "nvim/pos_defs.h"
#include "nvim/regexp.h"
#include "nvim/runtime.h"
#include "nvim/search.h"
@@ -104,9 +102,9 @@
#include "nvim/spellsuggest.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/types.h"
+#include "nvim/types_defs.h"
#include "nvim/undo.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#include "nvim/window.h"
// Result values. Lower number is accepted over higher one.
@@ -150,7 +148,7 @@ typedef struct matchinf_S {
// for when checking a compound word
int mi_compoff; // start of following word offset
- char_u mi_compflags[MAXWLEN]; // flags for compound words used
+ uint8_t mi_compflags[MAXWLEN]; // flags for compound words used
int mi_complen; // nr of compound words used
int mi_compextra; // nr of COMPOUNDROOT words
@@ -184,12 +182,21 @@ int did_set_spelltab;
# include "spell.c.generated.h"
#endif
-// mode values for find_word
-#define FIND_FOLDWORD 0 // find word case-folded
-#define FIND_KEEPWORD 1 // find keep-case word
-#define FIND_PREFIX 2 // find word after prefix
-#define FIND_COMPOUND 3 // find case-folded compound word
-#define FIND_KEEPCOMPOUND 4 // find keep-case compound word
+/// mode values for find_word
+enum {
+ FIND_FOLDWORD = 0, ///< find word case-folded
+ FIND_KEEPWORD = 1, ///< find keep-case word
+ FIND_PREFIX = 2, ///< find word after prefix
+ FIND_COMPOUND = 3, ///< find case-folded compound word
+ FIND_KEEPCOMPOUND = 4, ///< find keep-case compound word
+};
+
+/// type values for get_char_type
+enum {
+ CHAR_OTHER = 0,
+ CHAR_UPPER = 1,
+ CHAR_DIGIT = 2,
+};
char *e_format = N_("E759: Format error in spell file");
@@ -222,7 +229,7 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount
size_t wrongcaplen = 0;
bool count_word = docount;
bool use_camel_case = (wp->w_s->b_p_spo_flags & SPO_CAMEL) != 0;
- bool camel_case = false;
+ bool is_camel_case = false;
// A word never starts at a space or a control character. Return quickly
// then, skipping over the character.
@@ -255,24 +262,14 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount
mi.mi_word = ptr;
mi.mi_fend = ptr;
if (spell_iswordp(mi.mi_fend, wp)) {
- bool this_upper = false; // init for gcc
-
if (use_camel_case) {
- int c = utf_ptr2char(mi.mi_fend);
- this_upper = SPELL_ISUPPER(c);
+ mi.mi_fend = advance_camelcase_word(ptr, wp, &is_camel_case);
+ } else {
+ do {
+ MB_PTR_ADV(mi.mi_fend);
+ } while (*mi.mi_fend != NUL && spell_iswordp(mi.mi_fend, wp));
}
- do {
- MB_PTR_ADV(mi.mi_fend);
- if (use_camel_case) {
- const bool prev_upper = this_upper;
- int c = utf_ptr2char(mi.mi_fend);
- this_upper = SPELL_ISUPPER(c);
- camel_case = !prev_upper && this_upper;
- }
- } while (*mi.mi_fend != NUL && spell_iswordp(mi.mi_fend, wp)
- && !camel_case);
-
if (capcol != NULL && *capcol == 0 && wp->w_s->b_cap_prog != NULL) {
// Check word starting with capital letter.
int c = utf_ptr2char(ptr);
@@ -304,7 +301,7 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount
MAXWLEN + 1);
mi.mi_fwordlen = (int)strlen(mi.mi_fword);
- if (camel_case && mi.mi_fwordlen > 0) {
+ if (is_camel_case && mi.mi_fwordlen > 0) {
// introduce a fake word end space into the folded word.
mi.mi_fword[mi.mi_fwordlen - 1] = ' ';
}
@@ -380,7 +377,7 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount
MB_PTR_ADV(mi.mi_end);
} else if (mi.mi_result == SP_BAD
&& LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) {
- char *p, *fp;
+ char *p;
int save_result = mi.mi_result;
// First language in 'spelllang' is NOBREAK. Find first position
@@ -388,8 +385,8 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount
mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, 0);
if (mi.mi_lp->lp_slang->sl_fidxs != NULL) {
p = mi.mi_word;
- fp = mi.mi_fword;
- for (;;) {
+ char *fp = mi.mi_fword;
+ while (true) {
MB_PTR_ADV(p);
MB_PTR_ADV(fp);
if (p >= mi.mi_end) {
@@ -424,6 +421,66 @@ size_t spell_check(win_T *wp, char *ptr, hlf_T *attrp, int *capcol, bool docount
return (size_t)(mi.mi_end - ptr);
}
+/// Determine the type of character "c".
+static int get_char_type(int c)
+{
+ if (ascii_isdigit(c)) {
+ return CHAR_DIGIT;
+ }
+ if (SPELL_ISUPPER(c)) {
+ return CHAR_UPPER;
+ }
+ return CHAR_OTHER;
+}
+
+/// Returns a pointer to the end of the word starting at "str".
+/// Supports camelCase words.
+static char *advance_camelcase_word(char *str, win_T *wp, bool *is_camel_case)
+{
+ char *end = str;
+
+ *is_camel_case = false;
+
+ if (*str == NUL) {
+ return str;
+ }
+
+ int c = utf_ptr2char(end);
+ MB_PTR_ADV(end);
+ // We need at most the types of the type of the last two chars.
+ int last_last_type = -1;
+ int last_type = get_char_type(c);
+
+ while (*end != NUL && spell_iswordp(end, wp)) {
+ c = utf_ptr2char(end);
+ int this_type = get_char_type(c);
+
+ if (last_last_type == CHAR_UPPER && last_type == CHAR_UPPER
+ && this_type == CHAR_OTHER) {
+ // Handle the following cases:
+ // UpperUpperLower
+ *is_camel_case = true;
+ // Back up by one char.
+ MB_PTR_BACK(str, end);
+ break;
+ } else if ((this_type == CHAR_UPPER && last_type == CHAR_OTHER)
+ || (this_type != last_type
+ && (this_type == CHAR_DIGIT || last_type == CHAR_DIGIT))) {
+ // Handle the following cases:
+ // LowerUpper LowerDigit UpperDigit DigitUpper DigitLower
+ *is_camel_case = true;
+ break;
+ }
+
+ last_last_type = last_type;
+ last_type = this_type;
+
+ MB_PTR_ADV(end);
+ }
+
+ return end;
+}
+
// Check if the word at "mip->mi_word" is in the tree.
// When "mode" is FIND_FOLDWORD check in fold-case word tree.
// When "mode" is FIND_KEEPWORD check in keep-case word tree.
@@ -437,14 +494,14 @@ static void find_word(matchinf_T *mip, int mode)
int flen;
char *ptr;
slang_T *slang = mip->mi_lp->lp_slang;
- char_u *byts;
+ uint8_t *byts;
idx_T *idxs;
if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) {
// Check for word with matching case in keep-case tree.
ptr = mip->mi_word;
flen = 9999; // no case folding, always enough bytes
- byts = (char_u *)slang->sl_kbyts;
+ byts = slang->sl_kbyts;
idxs = slang->sl_kidxs;
if (mode == FIND_KEEPCOMPOUND) {
@@ -455,7 +512,7 @@ static void find_word(matchinf_T *mip, int mode)
// Check for case-folded in case-folded tree.
ptr = mip->mi_fword;
flen = mip->mi_fwordlen; // available case-folded bytes
- byts = (char_u *)slang->sl_fbyts;
+ byts = slang->sl_fbyts;
idxs = slang->sl_fidxs;
if (mode == FIND_PREFIX) {
@@ -482,7 +539,7 @@ static void find_word(matchinf_T *mip, int mode)
// - there is a byte that doesn't match,
// - we reach the end of the tree,
// - or we reach the end of the line.
- for (;;) {
+ while (true) {
if (flen <= 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
}
@@ -549,7 +606,7 @@ static void find_word(matchinf_T *mip, int mode)
// One space in the good word may stand for several spaces in the
// checked word.
if (c == ' ') {
- for (;;) {
+ while (true) {
if (flen <= 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
}
@@ -737,7 +794,7 @@ static void find_word(matchinf_T *mip, int mode)
// If the word ends the sequence of compound flags of the
// words must match with one of the COMPOUNDRULE items and
// the number of syllables must not be too large.
- mip->mi_compflags[mip->mi_complen] = (char_u)((unsigned)flags >> 24);
+ mip->mi_compflags[mip->mi_complen] = (uint8_t)((unsigned)flags >> 24);
mip->mi_compflags[mip->mi_complen + 1] = NUL;
if (word_ends) {
char fword[MAXWLEN] = { 0 };
@@ -795,9 +852,6 @@ static void find_word(matchinf_T *mip, int mode)
mip->mi_compoff = (int)(p - mip->mi_fword);
}
}
-#if 0
- c = mip->mi_compoff;
-#endif
mip->mi_complen++;
if (flags & WF_COMPROOT) {
mip->mi_compextra++;
@@ -823,16 +877,6 @@ static void find_word(matchinf_T *mip, int mode)
// Find following word in keep-case tree.
mip->mi_compoff = wlen;
find_word(mip, FIND_KEEPCOMPOUND);
-
-#if 0 // Disabled, a prefix must not appear halfway through a compound
- // word, unless the COMPOUNDPERMITFLAG is used, in which case it
- // can't be a postponed prefix.
- if (!slang->sl_nobreak || mip->mi_result == SP_BAD) {
- // Check for following word with prefix.
- mip->mi_compoff = c;
- find_prefix(mip, FIND_COMPOUND);
- }
-#endif
}
if (!slang->sl_nobreak) {
@@ -961,10 +1005,10 @@ bool can_compound(slang_T *slang, const char *word, const uint8_t *flags)
// compound rule. This is used to stop trying a compound if the flags
// collected so far can't possibly match any compound rule.
// Caller must check that slang->sl_comprules is not NULL.
-bool match_compoundrule(slang_T *slang, const char_u *compflags)
+bool match_compoundrule(slang_T *slang, const uint8_t *compflags)
{
// loop over all the COMPOUNDRULE entries
- for (char_u *p = (char_u *)slang->sl_comprules; *p != NUL; p++) {
+ for (char *p = (char *)slang->sl_comprules; *p != NUL; p++) {
// loop over the flags in the compound word we have made, match
// them against the current rule entry
for (int i = 0;; i++) {
@@ -982,21 +1026,21 @@ bool match_compoundrule(slang_T *slang, const char_u *compflags)
// compare against all the flags in []
p++;
while (*p != ']' && *p != NUL) {
- if (*p++ == c) {
+ if ((uint8_t)(*p++) == c) {
match = true;
}
}
if (!match) {
break; // none matches
}
- } else if (*p != c) {
+ } else if ((uint8_t)(*p) != c) {
break; // flag of word doesn't match flag in pattern
}
p++;
}
// Skip to the next "/", where the next pattern starts.
- p = (char_u *)vim_strchr((char *)p, '/');
+ p = vim_strchr(p, '/');
if (p == NULL) {
break;
}
@@ -1062,13 +1106,13 @@ static void find_prefix(matchinf_T *mip, int mode)
int wlen = 0;
slang_T *slang = mip->mi_lp->lp_slang;
- char_u *byts = (char_u *)slang->sl_pbyts;
+ uint8_t *byts = slang->sl_pbyts;
if (byts == NULL) {
return; // array is empty
}
// We use the case-folded word here, since prefixes are always
// case-folded.
- char_u *ptr = (char_u *)mip->mi_fword;
+ char *ptr = mip->mi_fword;
int flen = mip->mi_fwordlen; // available case-folded bytes
if (mode == FIND_COMPOUND) {
// Skip over the previously found word(s).
@@ -1081,7 +1125,7 @@ static void find_prefix(matchinf_T *mip, int mode)
// - there is a byte that doesn't match,
// - we reach the end of the tree,
// - or we reach the end of the line.
- for (;;) {
+ while (true) {
if (flen == 0 && *mip->mi_fend != NUL) {
flen = fold_more(mip);
}
@@ -1126,7 +1170,7 @@ static void find_prefix(matchinf_T *mip, int mode)
}
// Perform a binary search in the list of accepted bytes.
- int c = ptr[wlen];
+ int c = (uint8_t)ptr[wlen];
idx_T lo = arridx;
idx_T hi = arridx + len - 1;
while (lo < hi) {
@@ -1189,11 +1233,19 @@ bool spell_valid_case(int wordflags, int treeflags)
|| (wordflags & WF_ONECAP) != 0));
}
-// Returns true if spell checking is not enabled.
+/// Return true if spell checking is enabled for "wp".
+bool spell_check_window(win_T *wp)
+{
+ return wp->w_p_spell
+ && *wp->w_s->b_p_spl != NUL
+ && wp->w_s->b_langp.ga_len > 0
+ && *(char **)(wp->w_s->b_langp.ga_data) != NULL;
+}
+
+/// Return true and give an error if spell checking is not enabled.
bool no_spell_checking(win_T *wp)
{
- if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL
- || GA_EMPTY(&wp->w_s->b_langp)) {
+ if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL || GA_EMPTY(&wp->w_s->b_langp)) {
emsg(_(e_no_spell));
return true;
}
@@ -1203,19 +1255,18 @@ bool no_spell_checking(win_T *wp)
static void decor_spell_nav_start(win_T *wp)
{
decor_state = (DecorState){ 0 };
- decor_redraw_reset(wp->w_buffer, &decor_state);
+ decor_redraw_reset(wp, &decor_state);
}
-static bool decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_lnum, int col,
- char **decor_error)
+static TriState decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_lnum, int col)
{
if (*decor_lnum != lnum) {
- decor_providers_invoke_spell(wp, lnum - 1, col, lnum - 1, -1, decor_error);
- decor_redraw_line(wp->w_buffer, lnum - 1, &decor_state);
+ decor_providers_invoke_spell(wp, lnum - 1, col, lnum - 1, -1);
+ decor_redraw_line(wp, lnum - 1, &decor_state);
*decor_lnum = lnum;
}
- decor_redraw_col(wp->w_buffer, col, col, false, &decor_state);
- return decor_state.spell == kTrue;
+ decor_redraw_col(wp, col, 0, false, &decor_state);
+ return decor_state.spell;
}
static inline bool can_syn_spell(win_T *wp, linenr_T lnum, int col)
@@ -1269,7 +1320,6 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
linenr_T lnum = wp->w_cursor.lnum;
clearpos(&found_pos);
- char *decor_error = NULL;
// Ephemeral extmarks are currently stored in the global decor_state.
// When looking for spell errors, we need to:
// - temporarily reset decor_state
@@ -1283,7 +1333,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
decor_spell_nav_start(wp);
while (!got_int) {
- char *line = ml_get_buf(wp->w_buffer, lnum, false);
+ char *line = ml_get_buf(wp->w_buffer, lnum);
len = strlen(line);
if (buflen < len + MAXWLEN + 2) {
@@ -1304,23 +1354,23 @@ 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;
}
// Need to get the line again, may have looked at the previous
// one.
- line = ml_get_buf(wp->w_buffer, lnum, false);
+ line = ml_get_buf(wp->w_buffer, lnum);
}
// Copy the line into "buf" and append the start of the next line if
// possible. Note: this ml_get_buf() may make "line" invalid, check
// for empty line first.
- bool empty_line = *skipwhite((const char *)line) == NUL;
+ bool empty_line = *skipwhite(line) == NUL;
STRCPY(buf, line);
if (lnum < wp->w_buffer->b_ml.ml_line_count) {
spell_cat_line(buf + strlen(buf),
- ml_get_buf(wp->w_buffer, lnum + 1, false),
+ ml_get_buf(wp->w_buffer, lnum + 1),
MAXWLEN);
}
char *p = buf + skip;
@@ -1352,9 +1402,18 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
: p - buf) > wp->w_cursor.col)) {
col = (colnr_T)(p - buf);
- bool can_spell = (!has_syntax && (wp->w_s->b_p_spo_flags & SPO_NPBUFFER) == 0)
- || decor_spell_nav_col(wp, lnum, &decor_lnum, col, &decor_error)
- || (has_syntax && can_syn_spell(wp, lnum, col));
+ bool no_plain_buffer = (wp->w_s->b_p_spo_flags & SPO_NPBUFFER) != 0;
+ bool can_spell = !no_plain_buffer;
+ switch (decor_spell_nav_col(wp, lnum, &decor_lnum, col)) {
+ case kTrue:
+ can_spell = true; break;
+ case kFalse:
+ can_spell = false; break;
+ case kNone:
+ if (has_syntax) {
+ can_spell = can_syn_spell(wp, lnum, col);
+ }
+ }
if (!can_spell) {
attr = HLF_COUNT;
@@ -1471,7 +1530,6 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
theend:
decor_state_free(&decor_state);
- xfree(decor_error);
decor_state = saved_decor_start;
xfree(buf);
return ret;
@@ -1483,9 +1541,9 @@ theend:
// to skip those bytes if the word was OK.
void spell_cat_line(char *buf, char *line, int maxlen)
{
- char_u *p = (char_u *)skipwhite(line);
+ char *p = skipwhite(line);
while (vim_strchr("*#/\"\t", (uint8_t)(*p)) != NULL) {
- p = (char_u *)skipwhite((char *)p + 1);
+ p = skipwhite(p + 1);
}
if (*p == NUL) {
@@ -1494,10 +1552,10 @@ void spell_cat_line(char *buf, char *line, int maxlen)
// Only worth concatenating if there is something else than spaces to
// concatenate.
- int n = (int)(p - (char_u *)line) + 1;
+ int n = (int)(p - line) + 1;
if (n < maxlen - 1) {
memset(buf, ' ', (size_t)n);
- xstrlcpy(buf + n, (char *)p, (size_t)(maxlen - n));
+ xstrlcpy(buf + n, p, (size_t)(maxlen - n));
}
}
@@ -1553,7 +1611,7 @@ static void spell_load_lang(char *lang)
lang);
do_cmdline_cmd(autocmd_buf);
} else {
- smsg(_("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
+ smsg(0, _("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
lang, spell_enc(), lang);
}
} else if (sl.sl_slang != NULL) {
@@ -1700,23 +1758,32 @@ void slang_clear_sug(slang_T *lp)
// Load one spell file and store the info into a slang_T.
// Invoked through do_in_runtimepath().
-static void spell_load_cb(char *fname, void *cookie)
+static bool spell_load_cb(int num_fnames, char **fnames, bool all, void *cookie)
{
spelload_T *slp = (spelload_T *)cookie;
- slang_T *slang = spell_load_file(fname, slp->sl_lang, NULL, false);
- if (slang == NULL) {
- return;
- }
+ for (int i = 0; i < num_fnames; i++) {
+ slang_T *slang = spell_load_file(fnames[i], slp->sl_lang, NULL, false);
+
+ if (slang == NULL) {
+ continue;
+ }
- // When a previously loaded file has NOBREAK also use it for the
- // ".add" files.
- if (slp->sl_nobreak && slang->sl_add) {
- slang->sl_nobreak = true;
- } else if (slang->sl_nobreak) {
- slp->sl_nobreak = true;
+ // When a previously loaded file has NOBREAK also use it for the
+ // ".add" files.
+ if (slp->sl_nobreak && slang->sl_add) {
+ slang->sl_nobreak = true;
+ } else if (slang->sl_nobreak) {
+ slp->sl_nobreak = true;
+ }
+
+ slp->sl_slang = slang;
+
+ if (!all) {
+ break;
+ }
}
- slp->sl_slang = slang;
+ return num_fnames > 0;
}
/// Add a word to the hashtable of common words.
@@ -1743,12 +1810,12 @@ void count_common_word(slang_T *lp, char *word, int len, uint8_t count)
wordcount_T *wc;
hash_T hash = hash_hash(p);
const size_t p_len = strlen(p);
- hashitem_T *hi = hash_lookup(&lp->sl_wordcount, (const char *)p, p_len, hash);
+ hashitem_T *hi = hash_lookup(&lp->sl_wordcount, p, p_len, hash);
if (HASHITEM_EMPTY(hi)) {
- wc = xmalloc(sizeof(wordcount_T) + p_len);
+ wc = xmalloc(offsetof(wordcount_T, wc_word) + p_len + 1);
memcpy(wc->wc_word, p, p_len + 1);
wc->wc_count = count;
- hash_add_item(&lp->sl_wordcount, hi, (char *)wc->wc_word, hash);
+ hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash);
} else {
wc = HI2WC(hi);
wc->wc_count = (uint16_t)(wc->wc_count + count);
@@ -1775,7 +1842,7 @@ bool byte_in_str(uint8_t *str, int n)
int init_syl_tab(slang_T *slang)
{
ga_init(&slang->sl_syl_items, sizeof(syl_item_T), 4);
- char *p = vim_strchr((char *)slang->sl_syllable, '/');
+ char *p = vim_strchr(slang->sl_syllable, '/');
while (p != NULL) {
*p++ = NUL;
if (*p == NUL) { // trailing slash
@@ -1838,7 +1905,7 @@ static int count_syllables(slang_T *slang, const char *word)
// No recognized syllable item, at least a syllable char then?
int c = utf_ptr2char(p);
len = utfc_ptr2len(p);
- if (vim_strchr((char *)slang->sl_syllable, c) == NULL) {
+ if (vim_strchr(slang->sl_syllable, c) == NULL) {
skip = false; // No, search for next syllable
} else if (!skip) {
cnt++; // Yes, count it
@@ -1851,7 +1918,7 @@ static int count_syllables(slang_T *slang, const char *word)
/// Parse 'spelllang' and set w_s->b_langp accordingly.
/// @return NULL if it's OK, an untranslated error message otherwise.
-char *did_set_spelllang(win_T *wp)
+char *parse_spelllang(win_T *wp)
{
garray_T ga;
char *splp;
@@ -1863,14 +1930,12 @@ char *did_set_spelllang(win_T *wp)
int c;
char lang[MAXWLEN + 1];
char spf_name[MAXPATHL];
- int len;
char *p;
int round;
char *spf;
char *use_region = NULL;
bool dont_use_region = false;
bool nobreak = false;
- langp_T *lp, *lp2;
static bool recursive = false;
char *ret_msg = NULL;
char *spl_copy;
@@ -1900,7 +1965,7 @@ char *did_set_spelllang(win_T *wp)
// Get one language name.
copy_option_part(&splp, lang, MAXWLEN, ",");
region = NULL;
- len = (int)strlen(lang);
+ int len = (int)strlen(lang);
if (!valid_spelllang(lang)) {
continue;
@@ -1994,7 +2059,7 @@ char *did_set_spelllang(win_T *wp)
} else {
// This is probably an error. Give a warning and
// accept the words anyway.
- smsg(_("Warning: region %s not supported"),
+ smsg(0, _("Warning: region %s not supported"),
region);
}
} else {
@@ -2107,7 +2172,7 @@ char *did_set_spelllang(win_T *wp)
// REP items. If the language doesn't support it itself use another one
// with the same name. E.g. for "en-math" use "en".
for (int i = 0; i < ga.ga_len; i++) {
- lp = LANGP_ENTRY(ga, i);
+ langp_T *lp = LANGP_ENTRY(ga, i);
// sound folding
if (!GA_EMPTY(&lp->lp_slang->sl_sal)) {
@@ -2116,7 +2181,7 @@ char *did_set_spelllang(win_T *wp)
} else {
// find first similar language that does sound folding
for (int j = 0; j < ga.ga_len; j++) {
- lp2 = LANGP_ENTRY(ga, j);
+ langp_T *lp2 = LANGP_ENTRY(ga, j);
if (!GA_EMPTY(&lp2->lp_slang->sl_sal)
&& strncmp(lp->lp_slang->sl_name,
lp2->lp_slang->sl_name, 2) == 0) {
@@ -2133,7 +2198,7 @@ char *did_set_spelllang(win_T *wp)
} else {
// find first similar language that has REP items
for (int j = 0; j < ga.ga_len; j++) {
- lp2 = LANGP_ENTRY(ga, j);
+ langp_T *lp2 = LANGP_ENTRY(ga, j);
if (!GA_EMPTY(&lp2->lp_slang->sl_rep)
&& strncmp(lp->lp_slang->sl_name,
lp2->lp_slang->sl_name, 2) == 0) {
@@ -2167,14 +2232,14 @@ static void use_midword(slang_T *lp, win_T *wp)
return;
}
- for (char *p = (char *)lp->sl_midword; *p != NUL;) {
+ for (char *p = lp->sl_midword; *p != NUL;) {
const int c = utf_ptr2char(p);
const int l = utfc_ptr2len(p);
if (c < 256 && l <= 2) {
wp->w_s->b_spell_ismw[c] = true;
} else if (wp->w_s->b_spell_ismw_mb == NULL) {
// First multi-byte char in "b_spell_ismw_mb".
- wp->w_s->b_spell_ismw_mb = xstrnsave(p, (size_t)l);
+ wp->w_s->b_spell_ismw_mb = xmemdupz(p, (size_t)l);
} else {
// Append multi-byte chars to "b_spell_ismw_mb".
const int n = (int)strlen(wp->w_s->b_spell_ismw_mb);
@@ -2215,10 +2280,10 @@ static int find_region(const char *rp, const char *region)
/// @param[in] end End of word or NULL for NUL delimited string
///
/// @returns Case type of word
-int captype(char *word, const char *end)
+int captype(const char *word, const char *end)
FUNC_ATTR_NONNULL_ARG(1)
{
- char *p;
+ const char *p;
// find first letter
for (p = word; !spell_iswordp_nmw(p, curwin); MB_PTR_ADV(p)) {
@@ -2226,7 +2291,7 @@ int captype(char *word, const char *end)
return 0; // only non-word characters, illegal word
}
}
- int c = mb_ptr2char_adv((const char **)&p);
+ int c = mb_ptr2char_adv(&p);
bool allcap;
bool firstcap = allcap = SPELL_ISUPPER(c);
bool past_second = false; // past second word char
@@ -2309,7 +2374,7 @@ void spell_reload(void)
// window for this buffer in which 'spell' is set.
if (*wp->w_s->b_p_spl != NUL) {
if (wp->w_p_spell) {
- (void)did_set_spelllang(wp);
+ (void)parse_spelllang(wp);
break;
}
}
@@ -2354,8 +2419,8 @@ void clear_spell_chartab(spelltab_T *sp)
CLEAR_FIELD(sp->st_isu);
for (int i = 0; i < 256; i++) {
- sp->st_fold[i] = (char_u)i;
- sp->st_upper[i] = (char_u)i;
+ sp->st_fold[i] = (uint8_t)i;
+ sp->st_upper[i] = (uint8_t)i;
}
// We include digits. A word shouldn't start with a digit, but handling
@@ -2366,11 +2431,11 @@ void clear_spell_chartab(spelltab_T *sp)
for (int i = 'A'; i <= 'Z'; i++) {
sp->st_isw[i] = true;
sp->st_isu[i] = true;
- sp->st_fold[i] = (char_u)(i + 0x20);
+ sp->st_fold[i] = (uint8_t)(i + 0x20);
}
for (int i = 'a'; i <= 'z'; i++) {
sp->st_isw[i] = true;
- sp->st_upper[i] = (char_u)(i - 0x20);
+ sp->st_upper[i] = (uint8_t)(i - 0x20);
}
}
@@ -2391,8 +2456,8 @@ void init_spell_chartab(void)
// The folded/upper-cased value is different between latin1 and
// utf8 for 0xb5, causing E763 for no good reason. Use the latin1
// value for utf-8 to avoid this.
- spelltab.st_fold[i] = (f < 256) ? (char_u)f : (char_u)i;
- spelltab.st_upper[i] = (u < 256) ? (char_u)u : (char_u)i;
+ spelltab.st_fold[i] = (f < 256) ? (uint8_t)f : (uint8_t)i;
+ spelltab.st_upper[i] = (u < 256) ? (uint8_t)u : (uint8_t)i;
}
}
@@ -2480,7 +2545,7 @@ static bool spell_iswordp_w(const int *p, const win_T *wp)
// Uses the character definitions from the .spl file.
// When using a multi-byte 'encoding' the length may change!
// Returns FAIL when something wrong.
-int spell_casefold(const win_T *wp, char *str, int len, char *buf, int buflen)
+int spell_casefold(const win_T *wp, const char *str, int len, char *buf, int buflen)
FUNC_ATTR_NONNULL_ALL
{
if (len >= buflen) {
@@ -2491,12 +2556,12 @@ int spell_casefold(const win_T *wp, char *str, int len, char *buf, int buflen)
int outi = 0;
// Fold one character at a time.
- for (char *p = str; p < str + len;) {
+ for (const char *p = str; p < str + len;) {
if (outi + MB_MAXBYTES > buflen) {
buf[outi] = NUL;
return FAIL;
}
- int c = mb_cptr2char_adv((const char **)&p);
+ int c = mb_cptr2char_adv(&p);
// Exception: greek capital sigma 0x03A3 folds to 0x03C3, except
// when it is the last character in a word, then it folds to
@@ -2519,25 +2584,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) : 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);
if (*skipwhite(line) == NUL) {
need_cap = true;
} else {
@@ -2554,13 +2618,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;
- for (;;) {
+ 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)
@@ -2569,7 +2633,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);
@@ -2588,9 +2652,11 @@ void ex_spellrepall(exarg_T *eap)
emsg(_("E752: No previous spell replacement"));
return;
}
- int addlen = (int)(strlen(repl_to) - strlen(repl_from));
+ const size_t repl_from_len = strlen(repl_from);
+ const size_t repl_to_len = strlen(repl_to);
+ const int addlen = (int)(repl_to_len - repl_from_len);
- size_t frompatlen = strlen(repl_from) + 7;
+ const size_t frompatlen = repl_from_len + 7;
char *frompat = xmalloc(frompatlen);
snprintf(frompat, frompatlen, "\\V\\<%s\\>", repl_from);
p_ws = false;
@@ -2599,7 +2665,7 @@ void ex_spellrepall(exarg_T *eap)
sub_nlines = 0;
curwin->w_cursor.lnum = 0;
while (!got_int) {
- if (do_search(NULL, '/', '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
+ if (do_search(NULL, '/', '/', frompat, 1, SEARCH_KEEP, NULL) == 0
|| u_save_cursor() == FAIL) {
break;
}
@@ -2607,14 +2673,15 @@ void ex_spellrepall(exarg_T *eap)
// Only replace when the right word isn't there yet. This happens
// when changing "etc" to "etc.".
char *line = get_cursor_line_ptr();
- if (addlen <= 0 || strncmp(line + curwin->w_cursor.col,
- repl_to, strlen(repl_to)) != 0) {
+ if (addlen <= 0
+ || strncmp(line + curwin->w_cursor.col, repl_to, repl_to_len) != 0) {
char *p = xmalloc(strlen(line) + (size_t)addlen + 1);
memmove(p, line, (size_t)curwin->w_cursor.col);
STRCPY(p + curwin->w_cursor.col, repl_to);
- STRCAT(p, line + curwin->w_cursor.col + strlen(repl_from));
+ STRCAT(p, line + curwin->w_cursor.col + repl_from_len);
ml_replace(curwin->w_cursor.lnum, p, false);
- changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
+ inserted_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col,
+ (int)repl_from_len, (int)repl_to_len);
if (curwin->w_cursor.lnum != prev_lnum) {
sub_nlines++;
@@ -2622,7 +2689,7 @@ void ex_spellrepall(exarg_T *eap)
}
sub_nsubs++;
}
- curwin->w_cursor.col += (colnr_T)strlen(repl_to);
+ curwin->w_cursor.col += (colnr_T)repl_to_len;
}
p_ws = save_ws;
@@ -2643,10 +2710,10 @@ void ex_spellrepall(exarg_T *eap)
/// @param[in] word source string to copy
/// @param[in,out] wcopy copied string, with case of first letter changed
/// @param[in] upper True to upper case, otherwise lower case
-void onecap_copy(char *word, char *wcopy, bool upper)
+void onecap_copy(const char *word, char *wcopy, bool upper)
{
- char *p = word;
- int c = mb_cptr2char_adv((const char **)&p);
+ const char *p = word;
+ int c = mb_cptr2char_adv(&p);
if (upper) {
c = SPELL_TOUPPER(c);
} else {
@@ -2658,26 +2725,26 @@ void onecap_copy(char *word, char *wcopy, bool upper)
// Make a copy of "word" with all the letters upper cased into
// "wcopy[MAXWLEN]". The result is NUL terminated.
-void allcap_copy(char *word, char *wcopy)
+void allcap_copy(const char *word, char *wcopy)
{
- char_u *d = (char_u *)wcopy;
- for (char *s = word; *s != NUL;) {
- int c = mb_cptr2char_adv((const char **)&s);
+ char *d = wcopy;
+ for (const char *s = word; *s != NUL;) {
+ int c = mb_cptr2char_adv(&s);
if (c == 0xdf) {
c = 'S';
- if (d - (char_u *)wcopy >= MAXWLEN - 1) {
+ if (d - wcopy >= MAXWLEN - 1) {
break;
}
- *d++ = (char_u)c;
+ *d++ = (char)c;
} else {
c = SPELL_TOUPPER(c);
}
- if (d - (char_u *)wcopy >= MAXWLEN - MB_MAXBYTES) {
+ if (d - wcopy >= MAXWLEN - MB_MAXBYTES) {
break;
}
- d += utf_char2bytes(c, (char *)d);
+ d += utf_char2bytes(c, d);
}
*d = NUL;
}
@@ -2777,7 +2844,7 @@ void spell_soundfold(slang_T *slang, char *inword, bool folded, char *res)
// Perform sound folding of "inword" into "res" according to SOFOFROM and
// SOFOTO lines.
-static void spell_soundfold_sofo(slang_T *slang, char *inword, char *res)
+static void spell_soundfold_sofo(slang_T *slang, const char *inword, char *res)
{
int ri = 0;
@@ -2785,8 +2852,8 @@ static void spell_soundfold_sofo(slang_T *slang, char *inword, char *res)
// The sl_sal_first[] table contains the translation for chars up to
// 255, sl_sal the rest.
- for (char *s = inword; *s != NUL;) {
- int c = mb_cptr2char_adv((const char **)&s);
+ for (const char *s = inword; *s != NUL;) {
+ int c = mb_cptr2char_adv(&s);
if (utf_class(c) == 0) {
c = ' ';
} else if (c < 256) {
@@ -2796,7 +2863,7 @@ static void spell_soundfold_sofo(slang_T *slang, char *inword, char *res)
if (ip == NULL) { // empty list, can't match
c = NUL;
} else {
- for (;;) { // find "c" in the list
+ while (true) { // find "c" in the list
if (*ip == 0) { // not found
c = NUL;
break;
@@ -2834,7 +2901,6 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
int j, z;
int reslen;
int k = 0;
- int z0;
int k0;
int n0;
int pri;
@@ -2846,8 +2912,8 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
// Remove accents, if wanted. We actually remove all non-word characters.
// But keep white space.
int wordlen = 0;
- for (const char *s = (char *)inword; *s != NUL;) {
- const char_u *t = (char_u *)s;
+ for (const char *s = inword; *s != NUL;) {
+ const char *t = s;
int c = mb_cptr2char_adv(&s);
if (slang->sl_rem_accents) {
if (utf_class(c) == 0) {
@@ -2858,7 +2924,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
did_white = true;
} else {
did_white = false;
- if (!spell_iswordp_nmw((char *)t, curwin)) {
+ if (!spell_iswordp_nmw(t, curwin)) {
continue;
}
}
@@ -2875,7 +2941,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
while ((c = word[i]) != NUL) {
// Start with the first rule that has the character in the word.
int n = slang->sl_sal_first[c & 0xff];
- z0 = 0;
+ int z0 = 0;
if (n >= 0) {
// Check all rules for the same index byte.
@@ -2915,10 +2981,10 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
}
k++;
}
- char_u *s = (char_u *)smp[n].sm_rules;
+ char *s = smp[n].sm_rules;
pri = 5; // default priority
- p0 = *s;
+ p0 = (uint8_t)(*s);
k0 = k;
while (*s == '-' && k > 1) {
k--;
@@ -2929,7 +2995,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
}
if (ascii_isdigit(*s)) {
// determine priority
- pri = *s - '0';
+ pri = (uint8_t)(*s) - '0';
s++;
}
if (*s == '^' && *(s + 1) == '^') {
@@ -2992,7 +3058,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
}
p0 = 5;
- s = (char_u *)smp[n0].sm_rules;
+ s = smp[n0].sm_rules;
while (*s == '-') {
// "k0" gets NOT reduced because
// "if (k0 == k)"
@@ -3002,7 +3068,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
s++;
}
if (ascii_isdigit(*s)) {
- p0 = *s - '0';
+ p0 = (uint8_t)(*s) - '0';
s++;
}
@@ -3033,8 +3099,8 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
// replace string
ws = smp[n].sm_to_w;
- s = (char_u *)smp[n].sm_rules;
- p0 = (vim_strchr((char *)s, '<') != NULL) ? 1 : 0;
+ s = smp[n].sm_rules;
+ p0 = (vim_strchr(s, '<') != NULL) ? 1 : 0;
if (p0 == 1 && z == 0) {
// rule with '<' is used
if (reslen > 0 && ws != NULL && *ws != NUL
@@ -3077,7 +3143,7 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res)
} else {
c = *ws;
}
- if (strstr((char *)s, "^^") != NULL) {
+ if (strstr(s, "^^") != NULL) {
if (c != NUL) {
wres[reslen++] = c;
}
@@ -3130,9 +3196,9 @@ void ex_spellinfo(exarg_T *eap)
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; lpi++) {
langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
msg_puts("file: ");
- msg_puts((const char *)lp->lp_slang->sl_fname);
+ msg_puts(lp->lp_slang->sl_fname);
msg_putchar('\n');
- const char *const p = (const char *)lp->lp_slang->sl_info;
+ const char *const p = lp->lp_slang->sl_info;
if (p != NULL) {
msg_puts(p);
msg_putchar('\n');
@@ -3153,17 +3219,15 @@ void ex_spelldump(exarg_T *eap)
if (no_spell_checking(curwin)) {
return;
}
- char *spl;
- long dummy;
- (void)get_option_value("spl", &dummy, &spl, NULL, OPT_LOCAL);
+ OptVal spl = get_option_value("spl", NULL, OPT_LOCAL, NULL);
// Create a new empty buffer in a new window.
do_cmdline_cmd("new");
// enable spelling locally in the new window
- set_option_value_give_err("spell", true, "", OPT_LOCAL);
- set_option_value_give_err("spl", dummy, spl, OPT_LOCAL);
- xfree(spl);
+ set_option_value_give_err("spell", BOOLEAN_OPTVAL(true), OPT_LOCAL);
+ set_option_value_give_err("spl", spl, OPT_LOCAL);
+ optval_free(spl);
if (!buf_is_empty(curbuf)) {
return;
@@ -3195,7 +3259,7 @@ void spell_dump_compl(char *pat, int ic, Direction *dir, int dumpflags_arg)
int curi[MAXWLEN];
char word[MAXWLEN];
int c;
- char *byts;
+ uint8_t *byts;
idx_T *idxs;
linenr_T lnum = 0;
int depth;
@@ -3238,11 +3302,9 @@ void spell_dump_compl(char *pat, int ic, Direction *dir, int dumpflags_arg)
}
}
- if (do_region && region_names != NULL) {
- if (pat == NULL) {
- vim_snprintf(IObuff, IOSIZE, "/regions=%s", region_names);
- ml_append(lnum++, IObuff, (colnr_T)0, false);
- }
+ if (do_region && region_names != NULL && pat == NULL) {
+ vim_snprintf(IObuff, IOSIZE, "/regions=%s", region_names);
+ ml_append(lnum++, IObuff, 0, false);
} else {
do_region = false;
}
@@ -3257,7 +3319,7 @@ void spell_dump_compl(char *pat, int ic, Direction *dir, int dumpflags_arg)
if (pat == NULL) {
vim_snprintf(IObuff, IOSIZE, "# file: %s", slang->sl_fname);
- ml_append(lnum++, IObuff, (colnr_T)0, false);
+ ml_append(lnum++, IObuff, 0, false);
}
// When matching with a pattern and there are no prefixes only use
@@ -3297,7 +3359,7 @@ void spell_dump_compl(char *pat, int ic, Direction *dir, int dumpflags_arg)
// Do one more byte at this node.
n = arridx[depth] + curi[depth];
curi[depth]++;
- c = (uint8_t)byts[n];
+ c = byts[n];
if (c == 0 || depth >= MAXWLEN - 1) {
// End of word or reached maximum length, deal with the
// word.
@@ -3426,7 +3488,7 @@ static void dump_word(slang_T *slang, char *word, char *pat, Direction *dir, int
}
}
- ml_append(lnum, p, (colnr_T)0, false);
+ ml_append(lnum, p, 0, false);
} else if (((dumpflags & DUMPFLAG_ICASE)
? mb_strnicmp(p, pat, strlen(pat)) == 0
: strncmp(p, pat, strlen(pat)) == 0)
@@ -3463,7 +3525,7 @@ static linenr_T dump_prefixes(slang_T *slang, char *word, char *pat, Direction *
has_word_up = true;
}
- char_u *byts = (char_u *)slang->sl_pbyts;
+ uint8_t *byts = slang->sl_pbyts;
idx_T *idxs = slang->sl_pidxs;
if (byts != NULL) { // array not is empty
// Loop over all prefixes, building them byte-by-byte in prefix[].
@@ -3585,7 +3647,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.
@@ -3613,16 +3675,16 @@ bool valid_spellfile(const char *val)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
for (const char *s = val; *s != NUL; s++) {
- if (!vim_isfilec((uint8_t)(*s)) && *s != ',' && *s != ' ') {
+ if (!vim_is_fname_char((uint8_t)(*s))) {
return false;
}
}
return true;
}
-char *did_set_spell_option(bool is_spellfile)
+const char *did_set_spell_option(bool is_spellfile)
{
- char *errmsg = NULL;
+ const char *errmsg = NULL;
if (is_spellfile) {
int l = (int)strlen(curwin->w_s->b_p_spf);
@@ -3638,7 +3700,7 @@ char *did_set_spell_option(bool is_spellfile)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer == curbuf && wp->w_p_spell) {
- errmsg = did_set_spelllang(wp);
+ errmsg = parse_spelllang(wp);
break;
}
}
@@ -3647,7 +3709,7 @@ char *did_set_spell_option(bool is_spellfile)
/// Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
/// Return error message when failed, NULL when OK.
-char *compile_cap_prog(synblock_T *synblock)
+const char *compile_cap_prog(synblock_T *synblock)
FUNC_ATTR_NONNULL_ALL
{
regprog_T *rp = synblock->b_cap_prog;