mirror of
https://github.com/vim/vim.git
synced 2025-07-24 10:45:12 -04:00
updated for version 7.0095
This commit is contained in:
parent
238f4fa798
commit
cf6bf39f68
291
src/spell.c
291
src/spell.c
@ -86,9 +86,10 @@
|
||||
* <regioncnt> <regionname> ...
|
||||
* <charflagslen> <charflags>
|
||||
* <fcharslen> <fchars>
|
||||
* <midwordlen> <midword>
|
||||
* <prefcondcnt> <prefcond> ...
|
||||
*
|
||||
* <fileID> 10 bytes "VIMspell07"
|
||||
* <fileID> 10 bytes "VIMspell08"
|
||||
* <regioncnt> 1 byte number of regions following (8 supported)
|
||||
* <regionname> 2 bytes Region name: ca, au, etc. Lower case.
|
||||
* First <regionname> is region 1.
|
||||
@ -100,6 +101,10 @@
|
||||
* <fcharslen> 2 bytes Number of bytes in <fchars>.
|
||||
* <fchars> N bytes Folded characters, first one is for character 128.
|
||||
*
|
||||
* <midwordlen> 2 bytes Number of bytes in <midword>.
|
||||
* <midword> N bytes Characters that are word characters only when used
|
||||
* in the middle of a word.
|
||||
*
|
||||
* <prefcondcnt> 2 bytes Number of <prefcond> items following.
|
||||
*
|
||||
* <prefcond> : <condlen> <condstr>
|
||||
@ -169,9 +174,11 @@
|
||||
* <byte> 1 byte Byte value of the sibling. Special cases:
|
||||
* BY_NOFLAGS: End of word without flags and for all
|
||||
* regions.
|
||||
* BY_FLAGS: End of word, <flags> follow. For
|
||||
* PREFIXTREE <prefixID> and <prefcondnr>
|
||||
* follow.
|
||||
* For PREFIXTREE <prefixID> and
|
||||
* <prefcondnr> follow.
|
||||
* BY_FLAGS: End of word, <flags> follow.
|
||||
* For PREFIXTREE <prefixID> and
|
||||
* <prefcondnr> follow for rare prefix.
|
||||
* BY_INDEX: Child of sibling is shared, <nodeidx>
|
||||
* and <xbyte> follow.
|
||||
*
|
||||
@ -235,6 +242,10 @@ typedef long idx_T;
|
||||
|
||||
#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP)
|
||||
|
||||
#define WF_RAREPFX 0x1000000 /* in sl_pidxs: flag for rare postponed
|
||||
prefix; must be above prefixID (one byte)
|
||||
and prefcondnr (two bytes) */
|
||||
|
||||
#define BY_NOFLAGS 0 /* end of word without flags or region */
|
||||
#define BY_FLAGS 1 /* end of word, flag byte follows */
|
||||
#define BY_INDEX 2 /* child is shared, index follows */
|
||||
@ -343,7 +354,7 @@ typedef struct langp_S
|
||||
#define SP_LOCAL 2
|
||||
#define SP_BAD 3
|
||||
|
||||
#define VIMSPELLMAGIC "VIMspell07" /* string at start of Vim spell file */
|
||||
#define VIMSPELLMAGIC "VIMspell08" /* string at start of Vim spell file */
|
||||
#define VIMSPELLMAGICL 10
|
||||
|
||||
/*
|
||||
@ -399,6 +410,7 @@ typedef struct suggest_S
|
||||
#define SCORE_DELDUP 64 /* delete a duplicated character */
|
||||
#define SCORE_INS 96 /* insert a character */
|
||||
#define SCORE_INSDUP 66 /* insert a duplicate character */
|
||||
#define SCORE_NONWORD 103 /* change non-word to word char */
|
||||
|
||||
#define SCORE_MAXINIT 350 /* Initial maximum score: higher == slower.
|
||||
* 350 allows for about three changes. */
|
||||
@ -449,6 +461,10 @@ typedef struct spelltab_S
|
||||
|
||||
static spelltab_T spelltab;
|
||||
static int did_set_spelltab;
|
||||
static char_u spell_ismw[256]; /* flags: is midword char */
|
||||
#ifdef FEAT_MBYTE
|
||||
static char_u *spell_ismw_mb = NULL; /* multi-byte midword chars */
|
||||
#endif
|
||||
|
||||
#define CF_WORD 0x01
|
||||
#define CF_UPPER 0x02
|
||||
@ -961,15 +977,20 @@ find_word(mip, mode)
|
||||
|
||||
/* When mode is FIND_PREFIX the word must support the prefix:
|
||||
* check the prefix ID and the condition. Do that for the list at
|
||||
* mip->mi_prefarridx. */
|
||||
* mip->mi_prefarridx that find_prefix() filled. */
|
||||
if (mode == FIND_PREFIX)
|
||||
{
|
||||
/* The prefix ID is stored two bytes above the flags. */
|
||||
prefid = (unsigned)flags >> 16;
|
||||
if (!valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx,
|
||||
c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx,
|
||||
prefid, mip->mi_fword + mip->mi_prefixlen,
|
||||
slang))
|
||||
slang);
|
||||
if (c == 0)
|
||||
continue;
|
||||
|
||||
/* Use the WF_RARE flag for a rare prefix. */
|
||||
if (c & WF_RAREPFX)
|
||||
flags |= WF_RARE;
|
||||
}
|
||||
|
||||
if (flags & WF_BANNED)
|
||||
@ -1006,8 +1027,9 @@ find_word(mip, mode)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if the prefix indicated by "mip->mi_prefarridx" matches with
|
||||
* the prefix ID "prefid" for the word "word".
|
||||
* Return non-zero if the prefix indicated by "mip->mi_prefarridx" matches
|
||||
* with the prefix ID "prefid" for the word "word".
|
||||
* The WF_RAREPFX flag is included in the return value for a rare prefix.
|
||||
*/
|
||||
static int
|
||||
valid_word_prefix(totprefcnt, arridx, prefid, word, slang)
|
||||
@ -1031,8 +1053,8 @@ valid_word_prefix(totprefcnt, arridx, prefid, word, slang)
|
||||
continue;
|
||||
|
||||
/* Check the condition, if there is one. The condition index is
|
||||
* stored above the prefix ID byte. */
|
||||
rp = slang->sl_prefprog[(unsigned)pidx >> 8];
|
||||
* stored in the two bytes above the prefix ID byte. */
|
||||
rp = slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff];
|
||||
if (rp != NULL)
|
||||
{
|
||||
regmatch.regprog = rp;
|
||||
@ -1041,10 +1063,10 @@ valid_word_prefix(totprefcnt, arridx, prefid, word, slang)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* It's a match! */
|
||||
return TRUE;
|
||||
/* It's a match! Return the WF_RAREPFX flag. */
|
||||
return pidx;
|
||||
}
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1647,6 +1669,7 @@ spell_load_file(fname, lang, old_lp, silent)
|
||||
* <regioncnt> <regionname> ...
|
||||
* <charflagslen> <charflags>
|
||||
* <fcharslen> <fchars>
|
||||
* <midwordlen> <midword>
|
||||
* <prefcondcnt> <prefcond> ...
|
||||
*/
|
||||
for (i = 0; i < VIMSPELLMAGICL; ++i)
|
||||
@ -1719,6 +1742,52 @@ formerr:
|
||||
goto formerr;
|
||||
}
|
||||
|
||||
/* <midwordlen> <midword> */
|
||||
cnt = (getc(fd) << 8) + getc(fd);
|
||||
if (cnt < 0)
|
||||
goto truncerr;
|
||||
if (cnt > 0)
|
||||
{
|
||||
for (i = 0; i < cnt; ++i)
|
||||
if (i < MAXWLEN) /* truncate at reasonable length */
|
||||
buf[i] = getc(fd);
|
||||
if (i < MAXWLEN)
|
||||
buf[i] = NUL;
|
||||
else
|
||||
buf[MAXWLEN] = NUL;
|
||||
|
||||
/* The midword characters add up to any midword characters from other
|
||||
* .spel files. */
|
||||
for (p = buf; *p != NUL; )
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
{
|
||||
c = mb_ptr2char(p);
|
||||
i = mb_ptr2len_check(p);
|
||||
if (c < 256)
|
||||
spell_ismw[c] = TRUE;
|
||||
else if (spell_ismw_mb == NULL)
|
||||
/* First multi-byte char in "spell_ismw_mb". */
|
||||
spell_ismw_mb = vim_strnsave(p, i);
|
||||
else
|
||||
{
|
||||
/* Append multi-byte chars to "spell_ismw_mb". */
|
||||
n = STRLEN(spell_ismw_mb);
|
||||
bp = vim_strnsave(spell_ismw_mb, n + i);
|
||||
if (bp != NULL)
|
||||
{
|
||||
vim_free(spell_ismw_mb);
|
||||
spell_ismw_mb = bp;
|
||||
vim_strncpy(bp + n, p, i);
|
||||
}
|
||||
}
|
||||
p += i;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
spell_ismw[*p++] = TRUE;
|
||||
}
|
||||
|
||||
/* <prefcondcnt> <prefcond> ... */
|
||||
cnt = (getc(fd) << 8) + getc(fd); /* <prefcondcnt> */
|
||||
if (cnt > 0)
|
||||
@ -2004,6 +2073,7 @@ read_tree(fd, byts, idxs, maxidx, startidx, prefixtree, maxprefcondnr)
|
||||
int n;
|
||||
idx_T idx = startidx;
|
||||
int c;
|
||||
int c2;
|
||||
#define SHARED_MASK 0x8000000
|
||||
|
||||
len = getc(fd); /* <siblingcount> */
|
||||
@ -2022,24 +2092,28 @@ read_tree(fd, byts, idxs, maxidx, startidx, prefixtree, maxprefcondnr)
|
||||
return -1;
|
||||
if (c <= BY_SPECIAL)
|
||||
{
|
||||
if (c == BY_NOFLAGS)
|
||||
if (c == BY_NOFLAGS && !prefixtree)
|
||||
{
|
||||
/* No flags, all regions. */
|
||||
idxs[idx] = 0;
|
||||
c = 0;
|
||||
}
|
||||
else if (c == BY_FLAGS)
|
||||
else if (c == BY_FLAGS || c == BY_NOFLAGS)
|
||||
{
|
||||
if (prefixtree)
|
||||
{
|
||||
/* Read the prefix ID and the condition nr. In idxs[]
|
||||
* store the prefix ID in the low byte, the condition
|
||||
* index shifted up 8 bits. */
|
||||
c = getc(fd); /* <prefixID> */
|
||||
c2 = getc(fd); /* <prefixID> */
|
||||
n = (getc(fd) << 8) + getc(fd); /* <prefcondnr> */
|
||||
if (n >= maxprefcondnr)
|
||||
return -2;
|
||||
c = (n << 8) + c;
|
||||
c2 += (n << 8);
|
||||
if (c == BY_NOFLAGS)
|
||||
c = c2;
|
||||
else
|
||||
c = c2 | WF_RAREPFX;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2356,6 +2430,8 @@ spell_free_all()
|
||||
first_lang = lp->sl_next;
|
||||
slang_free(lp);
|
||||
}
|
||||
|
||||
init_spell_chartab();
|
||||
}
|
||||
# endif
|
||||
|
||||
@ -2452,6 +2528,7 @@ struct affentry_S
|
||||
char_u *ae_add; /* text to add to basic word (can be NULL) */
|
||||
char_u *ae_cond; /* condition (NULL for ".") */
|
||||
regprog_T *ae_prog; /* regexp program for ae_cond or NULL */
|
||||
int ae_rare; /* rare affix */
|
||||
};
|
||||
|
||||
/* Affix header from ".aff" file. Used for af_pref and af_suff. */
|
||||
@ -2536,6 +2613,7 @@ typedef struct spellinfo_S
|
||||
int si_collapse; /* soundsalike: ? */
|
||||
int si_rem_accents; /* soundsalike: remove accents */
|
||||
garray_T si_map; /* MAP info concatenated */
|
||||
char_u *si_midword; /* MIDWORD chars, alloc'ed string or NULL */
|
||||
garray_T si_prefcond; /* table with conditions for postponed
|
||||
* prefixes, each stored as a string */
|
||||
int si_newID; /* current value for ah_newID */
|
||||
@ -2595,6 +2673,7 @@ spell_read_aff(fname, spin)
|
||||
int do_rep;
|
||||
int do_sal;
|
||||
int do_map;
|
||||
int do_midword;
|
||||
int found_map = FALSE;
|
||||
hashitem_T *hi;
|
||||
|
||||
@ -2612,7 +2691,7 @@ spell_read_aff(fname, spin)
|
||||
{
|
||||
if (!spin->si_verbose)
|
||||
verbose_enter();
|
||||
smsg((char_u *)_("Reading affix file %s..."), fname);
|
||||
smsg((char_u *)_("Reading affix file %s ..."), fname);
|
||||
out_flush();
|
||||
if (!spin->si_verbose)
|
||||
verbose_leave();
|
||||
@ -2627,6 +2706,9 @@ spell_read_aff(fname, spin)
|
||||
/* Only do MAP lines when not done in another .aff file already. */
|
||||
do_map = spin->si_map.ga_len == 0;
|
||||
|
||||
/* Only do MIDWORD line when not done in another .aff file already */
|
||||
do_midword = spin->si_midword == NULL;
|
||||
|
||||
/*
|
||||
* Allocate and init the afffile_T structure.
|
||||
*/
|
||||
@ -2706,6 +2788,11 @@ spell_read_aff(fname, spin)
|
||||
smsg((char_u *)_("Conversion in %s not supported"), fname);
|
||||
#endif
|
||||
}
|
||||
else if (STRCMP(items[0], "MIDWORD") == 0 && itemcnt == 2)
|
||||
{
|
||||
if (do_midword)
|
||||
spin->si_midword = vim_strsave(items[1]);
|
||||
}
|
||||
else if (STRCMP(items[0], "NOSPLITSUGS") == 0 && itemcnt == 1)
|
||||
{
|
||||
/* ignored, we always split */
|
||||
@ -2793,12 +2880,21 @@ spell_read_aff(fname, spin)
|
||||
&& itemcnt >= 5)
|
||||
{
|
||||
affentry_T *aff_entry;
|
||||
int rare = FALSE;
|
||||
int lasti = 5;
|
||||
|
||||
/* Check for "rare" after the other info. */
|
||||
if (itemcnt > 5 && STRICMP(items[5], "rare") == 0)
|
||||
{
|
||||
rare = TRUE;
|
||||
lasti = 6;
|
||||
}
|
||||
|
||||
/* Myspell allows extra text after the item, but that might
|
||||
* mean mistakes go unnoticed. Require a comment-starter. */
|
||||
if (itemcnt > 5 && *items[5] != '#')
|
||||
if (itemcnt > lasti && *items[lasti] != '#')
|
||||
smsg((char_u *)_("Trailing text in %s line %d: %s"),
|
||||
fname, lnum, items[5]);
|
||||
fname, lnum, items[lasti]);
|
||||
|
||||
/* New item for an affix letter. */
|
||||
--aff_todo;
|
||||
@ -2806,6 +2902,7 @@ spell_read_aff(fname, spin)
|
||||
sizeof(affentry_T));
|
||||
if (aff_entry == NULL)
|
||||
break;
|
||||
aff_entry->ae_rare = rare;
|
||||
|
||||
if (STRCMP(items[2], "0") != 0)
|
||||
aff_entry->ae_chop = getroom_save(&spin->si_blocks,
|
||||
@ -2868,8 +2965,8 @@ spell_read_aff(fname, spin)
|
||||
p = (char_u *)"";
|
||||
else
|
||||
p = aff_entry->ae_add;
|
||||
tree_add_word(p, spin->si_prefroot, -1, idx,
|
||||
cur_aff->ah_newID, &spin->si_blocks);
|
||||
tree_add_word(p, spin->si_prefroot, rare ? -2 : -1,
|
||||
idx, cur_aff->ah_newID, &spin->si_blocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3160,7 +3257,7 @@ spell_read_dic(fname, spin, affile)
|
||||
{
|
||||
if (!spin->si_verbose)
|
||||
verbose_enter();
|
||||
smsg((char_u *)_("Reading dictionary file %s..."), fname);
|
||||
smsg((char_u *)_("Reading dictionary file %s ..."), fname);
|
||||
out_flush();
|
||||
if (!spin->si_verbose)
|
||||
verbose_leave();
|
||||
@ -3384,6 +3481,7 @@ store_aff_word(word, spin, afflist, affile, ht, xht, comb, flags, pfxlist)
|
||||
int retval = OK;
|
||||
int i;
|
||||
char_u *p;
|
||||
int use_flags;
|
||||
|
||||
todo = ht->ht_used;
|
||||
for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi)
|
||||
@ -3460,16 +3558,23 @@ store_aff_word(word, spin, afflist, affile, ht, xht, comb, flags, pfxlist)
|
||||
STRCAT(newword, ae->ae_add);
|
||||
}
|
||||
|
||||
/* Obey the "rare" flag of the affix. */
|
||||
if (ae->ae_rare)
|
||||
use_flags = flags | WF_RARE;
|
||||
else
|
||||
use_flags = flags;
|
||||
|
||||
/* Store the modified word. */
|
||||
if (store_word(newword, spin,
|
||||
flags, spin->si_region, pfxlist) == FAIL)
|
||||
if (store_word(newword, spin, use_flags,
|
||||
spin->si_region, pfxlist) == FAIL)
|
||||
retval = FAIL;
|
||||
|
||||
/* When added a suffix and combining is allowed also
|
||||
* try adding prefixes additionally. */
|
||||
if (xht != NULL && ah->ah_combine)
|
||||
if (store_aff_word(newword, spin, afflist, affile,
|
||||
xht, NULL, TRUE, flags, pfxlist) == FAIL)
|
||||
xht, NULL, TRUE, use_flags, pfxlist)
|
||||
== FAIL)
|
||||
retval = FAIL;
|
||||
}
|
||||
}
|
||||
@ -3514,7 +3619,7 @@ spell_read_wordfile(fname, spin)
|
||||
{
|
||||
if (!spin->si_verbose)
|
||||
verbose_enter();
|
||||
smsg((char_u *)_("Reading word file %s..."), fname);
|
||||
smsg((char_u *)_("Reading word file %s ..."), fname);
|
||||
out_flush();
|
||||
if (!spin->si_verbose)
|
||||
verbose_leave();
|
||||
@ -3817,8 +3922,8 @@ store_word(word, spin, flags, region, pfxlist)
|
||||
|
||||
/*
|
||||
* Add word "word" to a word tree at "root".
|
||||
* When "flags" is -1 we are adding to the prefix tree where flags don't
|
||||
* matter and "region" is the condition nr.
|
||||
* When "flags" < 0 we are adding to the prefix tree where flags is used for
|
||||
* "rare" and "region" is the condition nr.
|
||||
* Returns FAIL when out of memory.
|
||||
*/
|
||||
static int
|
||||
@ -4109,6 +4214,7 @@ write_vim_spell(fname, spin)
|
||||
/* <HEADER>: <fileID> <regioncnt> <regionname> ...
|
||||
* <charflagslen> <charflags>
|
||||
* <fcharslen> <fchars>
|
||||
* <midwordlen> <midword>
|
||||
* <prefcondcnt> <prefcond> ... */
|
||||
|
||||
/* <fileID> */
|
||||
@ -4146,16 +4252,28 @@ write_vim_spell(fname, spin)
|
||||
else
|
||||
write_spell_chartab(fd);
|
||||
|
||||
|
||||
if (spin->si_midword == NULL)
|
||||
put_bytes(fd, 0L, 2); /* <midwordlen> */
|
||||
else
|
||||
{
|
||||
i = STRLEN(spin->si_midword);
|
||||
put_bytes(fd, (long_u)i, 2); /* <midwordlen> */
|
||||
fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); /* <midword> */
|
||||
}
|
||||
|
||||
|
||||
/* Write the prefix conditions. */
|
||||
write_spell_prefcond(fd, &spin->si_prefcond);
|
||||
|
||||
/* <SUGGEST> : <repcount> <rep> ...
|
||||
* <salflags> <salcount> <sal> ...
|
||||
* <maplen> <mapstr> */
|
||||
|
||||
/* Sort the REP items. */
|
||||
qsort(spin->si_rep.ga_data, (size_t)spin->si_rep.ga_len,
|
||||
sizeof(fromto_T), rep_compare);
|
||||
|
||||
/* <SUGGEST> : <repcount> <rep> ...
|
||||
* <salflags> <salcount> <sal> ...
|
||||
* <maplen> <mapstr> */
|
||||
for (round = 1; round <= 2; ++round)
|
||||
{
|
||||
if (round == 1)
|
||||
@ -4302,7 +4420,10 @@ put_node(fd, node, index, regionmask, prefixtree)
|
||||
{
|
||||
/* In PREFIXTREE write the required prefixID and the
|
||||
* associated condition nr (stored in wn_region). */
|
||||
putc(BY_FLAGS, fd); /* <byte> */
|
||||
if (np->wn_flags == (char_u)-2)
|
||||
putc(BY_FLAGS, fd); /* <byte> rare */
|
||||
else
|
||||
putc(BY_NOFLAGS, fd); /* <byte> */
|
||||
putc(np->wn_prefixID, fd); /* <prefixID> */
|
||||
put_bytes(fd, (long_u)np->wn_region, 2); /* <prefcondnr> */
|
||||
}
|
||||
@ -4449,6 +4570,14 @@ mkspell(fcount, fnames, ascii, overwrite, added_word)
|
||||
incount = 1;
|
||||
vim_snprintf((char *)wfname, sizeof(wfname), "%s.spl", fnames[0]);
|
||||
}
|
||||
else if (fcount == 1)
|
||||
{
|
||||
/* For ":mkspell path/vim" output file is "path/vim.latin1.spl". */
|
||||
innames = &fnames[0];
|
||||
incount = 1;
|
||||
vim_snprintf((char *)wfname, sizeof(wfname), "%s.%s.spl", fnames[0],
|
||||
spin.si_ascii ? (char_u *)"ascii" : spell_enc());
|
||||
}
|
||||
else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0)
|
||||
{
|
||||
/* Name ends in ".spl", use as the file name. */
|
||||
@ -4608,7 +4737,7 @@ mkspell(fcount, fnames, ascii, overwrite, added_word)
|
||||
{
|
||||
if (added_word)
|
||||
verbose_enter();
|
||||
smsg((char_u *)_("Writing spell file %s..."), wfname);
|
||||
smsg((char_u *)_("Writing spell file %s ..."), wfname);
|
||||
out_flush();
|
||||
if (added_word)
|
||||
verbose_leave();
|
||||
@ -4637,6 +4766,7 @@ mkspell(fcount, fnames, ascii, overwrite, added_word)
|
||||
ga_clear(&spin.si_sal);
|
||||
ga_clear(&spin.si_map);
|
||||
ga_clear(&spin.si_prefcond);
|
||||
vim_free(spin.si_midword);
|
||||
|
||||
/* Free the .aff file structures. */
|
||||
for (i = 0; i < incount; ++i)
|
||||
@ -4829,8 +4959,11 @@ init_spell_chartab()
|
||||
|
||||
did_set_spelltab = FALSE;
|
||||
clear_spell_chartab(&spelltab);
|
||||
|
||||
vim_memset(spell_ismw, FALSE, sizeof(spell_ismw));
|
||||
#ifdef FEAT_MBYTE
|
||||
vim_free(spell_ismw_mb);
|
||||
spell_ismw_mb = NULL;
|
||||
|
||||
if (enc_dbcs)
|
||||
{
|
||||
/* DBCS: assume double-wide characters are word characters. */
|
||||
@ -5021,24 +5154,50 @@ set_spell_finish(new_st)
|
||||
|
||||
/*
|
||||
* Return TRUE if "p" points to a word character.
|
||||
* As a special case we see a single quote as a word character when it is
|
||||
* As a special case we see "midword" characters as word character when it is
|
||||
* followed by a word character. This finds they'there but not 'they there'.
|
||||
* Thus this only works properly when past the first character of the word.
|
||||
*/
|
||||
static int
|
||||
spell_iswordp(p)
|
||||
char_u *p;
|
||||
{
|
||||
char_u *s;
|
||||
|
||||
if (*p == '\'')
|
||||
s = p + 1;
|
||||
else
|
||||
s = p;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte && MB_BYTE2LEN(*s) > 1)
|
||||
return mb_get_class(s) >= 2;
|
||||
char_u *s;
|
||||
int l;
|
||||
int c;
|
||||
|
||||
if (has_mbyte)
|
||||
{
|
||||
l = MB_BYTE2LEN(*p);
|
||||
s = p;
|
||||
if (l == 1)
|
||||
{
|
||||
/* be quick for ASCII */
|
||||
if (spell_ismw[*p])
|
||||
{
|
||||
s = p + 1; /* skip a mid-word character */
|
||||
l = MB_BYTE2LEN(*s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = mb_ptr2char(p);
|
||||
if (c < 256 ? spell_ismw[c] : (spell_ismw_mb != NULL
|
||||
&& vim_strchr(spell_ismw_mb, c) != NULL))
|
||||
{
|
||||
s = p + l;
|
||||
l = MB_BYTE2LEN(*s);
|
||||
}
|
||||
}
|
||||
|
||||
if (l > 1)
|
||||
return mb_get_class(s) >= 2;
|
||||
return spelltab.st_isw[*s];
|
||||
}
|
||||
#endif
|
||||
return spelltab.st_isw[*s];
|
||||
|
||||
return spelltab.st_isw[spell_ismw[*p] ? p[1] : p[0]];
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5718,7 +5877,29 @@ suggest_try_change(su)
|
||||
|| !spell_iswordp(fword + sp->ts_fidx))
|
||||
&& sp->ts_fidx >= sp->ts_fidxtry)
|
||||
{
|
||||
/* The badword also ends: add suggestions, */
|
||||
/* The badword also ends: add suggestions. Give a penalty
|
||||
* when changing non-word char to word char, e.g., "thes,"
|
||||
* -> "these". */
|
||||
p = fword + sp->ts_fidx;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
mb_ptr_back(fword, p);
|
||||
else
|
||||
#endif
|
||||
--p;
|
||||
if (!spell_iswordp(p))
|
||||
{
|
||||
p = preword + STRLEN(preword);
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
mb_ptr_back(preword, p);
|
||||
else
|
||||
#endif
|
||||
--p;
|
||||
if (spell_iswordp(p))
|
||||
newscore += SCORE_NONWORD;
|
||||
}
|
||||
|
||||
add_suggestion(su, &su->su_ga, preword,
|
||||
sp->ts_fidx - repextra,
|
||||
sp->ts_score + newscore, 0, FALSE);
|
||||
@ -7093,10 +7274,13 @@ add_suggestion(su, gap, goodword, badlen, score, altscore, had_bonus)
|
||||
|
||||
if (score <= su->su_maxscore)
|
||||
{
|
||||
/* Check if the word is already there. */
|
||||
/* Check if the word is already there. Also check the length that is
|
||||
* being replaced "thes," -> "these" is a different suggestion from
|
||||
* "thes" -> "these". */
|
||||
stp = &SUG(*gap, 0);
|
||||
for (i = gap->ga_len - 1; i >= 0; --i)
|
||||
if (STRCMP(stp[i].st_word, goodword) == 0)
|
||||
if (STRCMP(stp[i].st_word, goodword) == 0
|
||||
&& stp[i].st_orglen == badlen)
|
||||
{
|
||||
/* Found it. Remember the lowest score. */
|
||||
if (stp[i].st_score > score)
|
||||
@ -8164,10 +8348,13 @@ apply_prefixes(slang, word, round, flags, startlnum)
|
||||
break;
|
||||
curi[depth] += i - 1;
|
||||
|
||||
if (valid_word_prefix(i, n, prefid, word, slang))
|
||||
i = valid_word_prefix(i, n, prefid, word, slang);
|
||||
if (i != 0)
|
||||
{
|
||||
vim_strncpy(prefix + depth, word, MAXWLEN - depth);
|
||||
dump_word(prefix, round, flags, lnum++);
|
||||
dump_word(prefix, round,
|
||||
(i & WF_RAREPFX) ? (flags | WF_RARE)
|
||||
: flags, lnum++);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user