0
0
mirror of https://github.com/vim/vim.git synced 2025-07-25 10:54:51 -04:00

updated for version 7.0103

This commit is contained in:
Bram Moolenaar 2005-07-05 21:36:03 +00:00
parent 0dc065ee7c
commit dfb9ac0021

View File

@ -179,10 +179,18 @@
* regions. * regions.
* For PREFIXTREE <prefixID> and * For PREFIXTREE <prefixID> and
* <prefcondnr> follow. * <prefcondnr> follow.
* BY_FLAGS: End of word, <flags> follow. * BY_FLAGS: End of word, <flags> follow.
* For PREFIXTREE <prefixID> and * For PREFIXTREE <prefixID> and
* <prefcondnr> follow for rare prefix. * <prefcondnr> follow for rare prefix.
* BY_INDEX: Child of sibling is shared, <nodeidx> * BY_FLAGS2: End of word, <flags> and <flags2>
* follow. Not used in PREFIXTREE.
* BY_PFX_NC: For PREFIXTREE <prefixID> and
* <prefcondnr> follow for non-combining
* prefix.
* BY_PFX_RNC: For PREFIXTREE <prefixID> and
* <prefcondnr> follow for non-combining
* rare prefix.
* BY_INDEX: Child of sibling is shared, <nodeidx>
* and <xbyte> follow. * and <xbyte> follow.
* *
* <nodeidx> 3 bytes Index of child for this sibling, MSB first. * <nodeidx> 3 bytes Index of child for this sibling, MSB first.
@ -199,6 +207,10 @@
* WF_REGION <region> follows * WF_REGION <region> follows
* WF_PFX <prefixID> follows * WF_PFX <prefixID> follows
* *
* <flags2> 1 byte Only used when there are postponed prefixes.
* Bitmask of:
* WF_HAS_AFF >> 8 word includes affix
*
* <region> 1 byte Bitmask for regions in which word is valid. When * <region> 1 byte Bitmask for regions in which word is valid. When
* omitted it's valid in all regions. * omitted it's valid in all regions.
* Lowest bit is for region 1. * Lowest bit is for region 1.
@ -243,20 +255,34 @@ typedef long idx_T;
#define WF_ALLCAP 0x04 /* word must be all capitals */ #define WF_ALLCAP 0x04 /* word must be all capitals */
#define WF_RARE 0x08 /* rare word */ #define WF_RARE 0x08 /* rare word */
#define WF_BANNED 0x10 /* bad word */ #define WF_BANNED 0x10 /* bad word */
#define WF_PFX 0x20 /* prefix ID list follows */ #define WF_PFX 0x20 /* prefix ID follows */
#define WF_FIXCAP 0x40 /* keep-case word, allcap not allowed */ #define WF_FIXCAP 0x40 /* keep-case word, allcap not allowed */
#define WF_KEEPCAP 0x80 /* keep-case word */ #define WF_KEEPCAP 0x80 /* keep-case word */
/* for <flags2>, shifted up one byte to be used in wn_flags */
#define WF_HAS_AFF 0x0100 /* word includes affix */
#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP) #define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP)
/* flags for postponed prefixes. Must be above prefixID (one byte)
* and prefcondnr (two bytes). */
#define WF_RAREPFX 0x1000000 /* in sl_pidxs: flag for rare postponed #define WF_RAREPFX 0x1000000 /* in sl_pidxs: flag for rare postponed
prefix; must be above prefixID (one byte) * prefix */
and prefcondnr (two bytes) */ #define WF_PFX_NC 0x2000000 /* in sl_pidxs: flag for non-combining
* postponed prefix */
#define BY_NOFLAGS 0 /* end of word without flags or region */ /* Special byte values for <byte>. Some are only used in the tree for
#define BY_FLAGS 1 /* end of word, flag byte follows */ * postponed prefixes, some only in the other trees. This is a bit messy... */
#define BY_INDEX 2 /* child is shared, index follows */ #define BY_NOFLAGS 0 /* end of word without flags or region; for
#define BY_SPECIAL BY_INDEX /* hightest special byte value */ * postponed prefix: not rare, combining */
#define BY_FLAGS 1 /* end of word, flags byte follows; for
* postponed prefix: rare, combining */
#define BY_INDEX 2 /* child is shared, index follows */
#define BY_FLAGS2 3 /* end of word, two flags bytes follow; never
* used in prefix tree */
#define BY_PFX_NC 3 /* postponed prefix: not rare, not combining */
#define BY_PFX_RNC 4 /* postponed prefix: rare, not combining */
#define BY_SPECIAL BY_PFX_RNC /* highest special byte value */
/* Info from "REP" and "SAL" entries in ".aff" file used in si_rep, sl_rep, /* Info from "REP" and "SAL" entries in ".aff" file used in si_rep, sl_rep,
* and si_sal. Not for sl_sal! * and si_sal. Not for sl_sal!
@ -302,8 +328,8 @@ typedef short salfirst_T;
* The "idxs" array stores the index of the child node corresponding to the * The "idxs" array stores the index of the child node corresponding to the
* byte in "byts". * byte in "byts".
* Exception: when the byte is zero, the word may end here and "idxs" holds * Exception: when the byte is zero, the word may end here and "idxs" holds
* the flags and region for the word. There may be several zeros in sequence * the flags, region mask and prefixID for the word. There may be several
* for alternative flag/region combinations. * zeros in sequence for alternative flag/region combinations.
*/ */
typedef struct slang_S slang_T; typedef struct slang_S slang_T;
struct slang_S struct slang_S
@ -503,19 +529,6 @@ static int spell_iswordp_w __ARGS((int *p, buf_T *buf));
#endif #endif
static void write_spell_prefcond __ARGS((FILE *fd, garray_T *gap)); static void write_spell_prefcond __ARGS((FILE *fd, garray_T *gap));
/*
* Return TRUE if "p" points to a word character. Like spell_iswordp() but
* without the special handling of a single quote.
* Checking for a word character is done very often, avoid the function call
* overhead.
*/
#ifdef FEAT_MBYTE
# define SPELL_ISWORDP(p) ((has_mbyte && MB_BYTE2LEN(*(p)) > 1) \
? (mb_get_class(p) >= 2) : spelltab.st_isw[*(p)])
#else
# define SPELL_ISWORDP(p) (spelltab.st_isw[*(p)])
#endif
/* /*
* For finding suggestions: At each node in the tree these states are tried: * For finding suggestions: At each node in the tree these states are tried:
*/ */
@ -585,7 +598,7 @@ static slang_T *slang_alloc __ARGS((char_u *lang));
static void slang_free __ARGS((slang_T *lp)); static void slang_free __ARGS((slang_T *lp));
static void slang_clear __ARGS((slang_T *lp)); static void slang_clear __ARGS((slang_T *lp));
static void find_word __ARGS((matchinf_T *mip, int mode)); static void find_word __ARGS((matchinf_T *mip, int mode));
static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int prefid, char_u *word, slang_T *slang)); static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang));
static void find_prefix __ARGS((matchinf_T *mip)); static void find_prefix __ARGS((matchinf_T *mip));
static int fold_more __ARGS((matchinf_T *mip)); static int fold_more __ARGS((matchinf_T *mip));
static int spell_valid_case __ARGS((int wordflags, int treeflags)); static int spell_valid_case __ARGS((int wordflags, int treeflags));
@ -822,7 +835,7 @@ spell_check(wp, ptr, attrp, capcol)
/* When we are at a non-word character there is no error, just /* When we are at a non-word character there is no error, just
* skip over the character (try looking for a word after it). */ * skip over the character (try looking for a word after it). */
else if (!SPELL_ISWORDP(ptr)) else if (!spell_iswordp_nmw(ptr))
{ {
if (capcol != NULL && wp->w_buffer->b_cap_prog != NULL) if (capcol != NULL && wp->w_buffer->b_cap_prog != NULL)
{ {
@ -886,7 +899,6 @@ find_word(mip, mode)
unsigned flags; unsigned flags;
char_u *byts; char_u *byts;
idx_T *idxs; idx_T *idxs;
int prefid;
if (mode == FIND_KEEPWORD) if (mode == FIND_KEEPWORD)
{ {
@ -1070,10 +1082,9 @@ find_word(mip, mode)
if (mode == FIND_PREFIX) if (mode == FIND_PREFIX)
{ {
/* The prefix ID is stored two bytes above the flags. */ /* The prefix ID is stored two bytes above the flags. */
prefid = (unsigned)flags >> 16;
c = 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, flags,
slang); mip->mi_fword + mip->mi_prefixlen, slang);
if (c == 0) if (c == 0)
continue; continue;
@ -1087,7 +1098,7 @@ find_word(mip, mode)
else if (flags & WF_REGION) else if (flags & WF_REGION)
{ {
/* Check region. */ /* Check region. */
if ((mip->mi_lp->lp_region & (flags >> 8)) != 0) if ((mip->mi_lp->lp_region & (flags >> 16)) != 0)
res = SP_OK; res = SP_OK;
else else
res = SP_LOCAL; res = SP_LOCAL;
@ -1116,15 +1127,15 @@ find_word(mip, mode)
} }
/* /*
* Return non-zero if the prefix indicated by "mip->mi_prefarridx" matches * Return non-zero if the prefix indicated by "arridx" matches with the prefix
* with the prefix ID "prefid" for the word "word". * ID in "flags" for the word "word".
* The WF_RAREPFX flag is included in the return value for a rare prefix. * The WF_RAREPFX flag is included in the return value for a rare prefix.
*/ */
static int static int
valid_word_prefix(totprefcnt, arridx, prefid, word, slang) valid_word_prefix(totprefcnt, arridx, flags, word, slang)
int totprefcnt; /* nr of prefix IDs */ int totprefcnt; /* nr of prefix IDs */
int arridx; /* idx in sl_pidxs[] */ int arridx; /* idx in sl_pidxs[] */
int prefid; int flags;
char_u *word; char_u *word;
slang_T *slang; slang_T *slang;
{ {
@ -1132,7 +1143,9 @@ valid_word_prefix(totprefcnt, arridx, prefid, word, slang)
int pidx; int pidx;
regprog_T *rp; regprog_T *rp;
regmatch_T regmatch; regmatch_T regmatch;
int prefid;
prefid = (unsigned)flags >> 24;
for (prefcnt = totprefcnt - 1; prefcnt >= 0; --prefcnt) for (prefcnt = totprefcnt - 1; prefcnt >= 0; --prefcnt)
{ {
pidx = slang->sl_pidxs[arridx + prefcnt]; pidx = slang->sl_pidxs[arridx + prefcnt];
@ -1141,6 +1154,11 @@ valid_word_prefix(totprefcnt, arridx, prefid, word, slang)
if (prefid != (pidx & 0xff)) if (prefid != (pidx & 0xff))
continue; continue;
/* Check if the prefix doesn't combine and the word already has a
* suffix. */
if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC))
continue;
/* Check the condition, if there is one. The condition index is /* Check the condition, if there is one. The condition index is
* stored in the two bytes above the prefix ID byte. */ * stored in the two bytes above the prefix ID byte. */
rp = slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff]; rp = slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff];
@ -1610,7 +1628,6 @@ slang_alloc(lang)
{ {
lp->sl_name = vim_strsave(lang); lp->sl_name = vim_strsave(lang);
ga_init2(&lp->sl_rep, sizeof(fromto_T), 10); ga_init2(&lp->sl_rep, sizeof(fromto_T), 10);
ga_init2(&lp->sl_sal, sizeof(salitem_T), 10);
} }
return lp; return lp;
} }
@ -1993,6 +2010,7 @@ formerr:
* SAL items * SAL items
*/ */
gap = &lp->sl_sal; gap = &lp->sl_sal;
ga_init2(gap, sizeof(salitem_T), 10);
if (ga_grow(gap, cnt) == FAIL) if (ga_grow(gap, cnt) == FAIL)
goto endFAIL; goto endFAIL;
@ -2443,7 +2461,7 @@ read_tree(fd, byts, idxs, maxidx, startidx, prefixtree, maxprefcondnr)
idxs[idx] = 0; idxs[idx] = 0;
c = 0; c = 0;
} }
else if (c == BY_FLAGS || c == BY_NOFLAGS) else if (c != BY_INDEX)
{ {
if (prefixtree) if (prefixtree)
{ {
@ -2455,21 +2473,28 @@ read_tree(fd, byts, idxs, maxidx, startidx, prefixtree, maxprefcondnr)
if (n >= maxprefcondnr) if (n >= maxprefcondnr)
return -2; return -2;
c2 += (n << 8); c2 += (n << 8);
if (c == BY_NOFLAGS)
c = c2; /* the byte value is misused to pass two flags: rare
else * and non-combining. */
c = c2 | WF_RAREPFX; if (c == BY_FLAGS || c == BY_PFX_RNC)
c2 |= WF_RAREPFX;
if (c == BY_PFX_NC || c == BY_PFX_RNC)
c2 |= WF_PFX_NC;
c = c2;
} }
else else /* c must be BY_FLAGS or BY_FLAGS2 */
{ {
/* Read flags and optional region and prefix ID. In /* Read flags and optional region and prefix ID. In
* idxs[] the flags go in the low byte, region above that * idxs[] the flags go in the low two bytes, region above
* and prefix ID above the region. */ * that and prefix ID above the region. */
c2 = c;
c = getc(fd); /* <flags> */ c = getc(fd); /* <flags> */
if (c2 == BY_FLAGS2)
c = (getc(fd) << 8) + c; /* <flags2> */
if (c & WF_REGION) if (c & WF_REGION)
c = (getc(fd) << 8) + c; /* <region> */ c = (getc(fd) << 16) + c; /* <region> */
if (c & WF_PFX) if (c & WF_PFX)
c = (getc(fd) << 16) + c; /* <prefixID> */ c = (getc(fd) << 24) + c; /* <prefixID> */
} }
idxs[idx] = c; idxs[idx] = c;
@ -3049,12 +3074,14 @@ struct wordnode_S
wordnode_T *wn_sibling; /* next sibling (alternate byte in word, wordnode_T *wn_sibling; /* next sibling (alternate byte in word,
always sorted) */ always sorted) */
char_u wn_byte; /* Byte for this node. NUL for word end */ char_u wn_byte; /* Byte for this node. NUL for word end */
char_u wn_flags; /* when wn_byte is NUL: WF_ flags */ short_u wn_flags; /* when wn_byte is NUL: WF_ flags */
short wn_region; /* when wn_byte is NUL: region mask; for short wn_region; /* when wn_byte is NUL: region mask; for
PREFIXTREE it's the prefcondnr */ PREFIXTREE it's the prefcondnr */
char_u wn_prefixID; /* supported/required prefix ID or 0 */ char_u wn_prefixID; /* supported/required prefix ID or 0 */
}; };
#define WN_MASK 0xffff /* mask relevant bits of "wn_flags" */
#define HI2WN(hi) (wordnode_T *)((hi)->hi_key) #define HI2WN(hi) (wordnode_T *)((hi)->hi_key)
/* /*
@ -3118,6 +3145,12 @@ static int put_node __ARGS((FILE *fd, wordnode_T *node, int index, int regionmas
static void mkspell __ARGS((int fcount, char_u **fnames, int ascii, int overwrite, int added_word)); static void mkspell __ARGS((int fcount, char_u **fnames, int ascii, int overwrite, int added_word));
static void init_spellfile __ARGS((void)); static void init_spellfile __ARGS((void));
/* values for wn_flags used in the postponed prefixes tree */
#define PFX_FLAGS -1 /* not rare, combining */
#define PFX_FLAGS_R -2 /* rare, combining */
#define PFX_FLAGS_NC -3 /* not rare, not combining */
#define PFX_FLAGS_RNC -4 /* rare, not combining */
/* /*
* Read the affix file "fname". * Read the affix file "fname".
* Returns an afffile_T, NULL for complete failure. * Returns an afffile_T, NULL for complete failure.
@ -3419,6 +3452,7 @@ spell_read_aff(fname, spin)
{ {
int idx; int idx;
char_u **pp; char_u **pp;
int n;
for (idx = spin->si_prefcond.ga_len - 1; idx >= 0; for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
--idx) --idx)
@ -3444,7 +3478,21 @@ spell_read_aff(fname, spin)
p = (char_u *)""; p = (char_u *)"";
else else
p = aff_entry->ae_add; p = aff_entry->ae_add;
tree_add_word(p, spin->si_prefroot, rare ? -2 : -1, if (rare)
{
if (cur_aff->ah_combine)
n = PFX_FLAGS_R;
else
n = PFX_FLAGS_RNC;
}
else
{
if (cur_aff->ah_combine)
n = PFX_FLAGS;
else
n = PFX_FLAGS_NC;
}
tree_add_word(p, spin->si_prefroot, n,
idx, cur_aff->ah_newID, &spin->si_blocks); idx, cur_aff->ah_newID, &spin->si_blocks);
} }
} }
@ -3979,6 +4027,7 @@ store_aff_word(word, spin, afflist, affile, ht, xht, comb, flags, pfxlist)
int i; int i;
char_u *p; char_u *p;
int use_flags; int use_flags;
char_u *use_pfxlist;
todo = ht->ht_used; todo = ht->ht_used;
for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi) for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi)
@ -4055,18 +4104,31 @@ store_aff_word(word, spin, afflist, affile, ht, xht, comb, flags, pfxlist)
use_flags = flags | WF_RARE; use_flags = flags | WF_RARE;
else else
use_flags = flags; use_flags = flags;
use_pfxlist = pfxlist;
/* When there are postponed prefixes... */
if (spin->si_prefroot != NULL)
{
/* ... add a flag to indicate an affix was used. */
use_flags |= WF_HAS_AFF;
/* ... don't use a prefix list if combining
* affixes is not allowed */
if (!ah->ah_combine || comb)
use_pfxlist = NULL;
}
/* Store the modified word. */ /* Store the modified word. */
if (store_word(newword, spin, use_flags, if (store_word(newword, spin, use_flags,
spin->si_region, pfxlist) == FAIL) spin->si_region, use_pfxlist) == FAIL)
retval = FAIL; retval = FAIL;
/* When added a suffix and combining is allowed also /* When added a suffix and combining is allowed also
* try adding prefixes additionally. */ * try adding prefixes additionally. */
if (xht != NULL && ah->ah_combine) if (xht != NULL && ah->ah_combine)
if (store_aff_word(newword, spin, afflist, affile, if (store_aff_word(newword, spin, afflist, affile,
xht, NULL, TRUE, use_flags, pfxlist) xht, NULL, TRUE,
== FAIL) use_flags, use_pfxlist) == FAIL)
retval = FAIL; retval = FAIL;
} }
} }
@ -4369,10 +4431,11 @@ wordtree_alloc(blp)
/* /*
* Store a word in the tree(s). * Store a word in the tree(s).
* Always store it in the case-folded tree. A keep-case word can also be used * Always store it in the case-folded tree. For a keep-case word this is
* with all caps. * useful when the word can also be used with all caps (no WF_FIXCAP flag) and
* used to find suggestions.
* For a keep-case word also store it in the keep-case tree. * For a keep-case word also store it in the keep-case tree.
* When "pfxlist" is not NULL store the word for each prefix ID. * When "pfxlist" is not NULL store the word for each postponed prefix ID.
*/ */
static int static int
store_word(word, spin, flags, region, pfxlist) store_word(word, spin, flags, region, pfxlist)
@ -4445,8 +4508,8 @@ tree_add_word(word, root, flags, region, prefixID, blp)
|| (node->wn_byte == NUL || (node->wn_byte == NUL
&& (flags < 0 && (flags < 0
? node->wn_prefixID < prefixID ? node->wn_prefixID < prefixID
: node->wn_flags < (flags & 0xff) : node->wn_flags < (flags & WN_MASK)
|| (node->wn_flags == (flags & 0xff) || (node->wn_flags == (flags & WN_MASK)
&& node->wn_prefixID < prefixID))))) && node->wn_prefixID < prefixID)))))
{ {
prev = &node->wn_sibling; prev = &node->wn_sibling;
@ -4456,7 +4519,7 @@ tree_add_word(word, root, flags, region, prefixID, blp)
|| node->wn_byte != word[i] || node->wn_byte != word[i]
|| (word[i] == NUL || (word[i] == NUL
&& (flags < 0 && (flags < 0
|| node->wn_flags != (flags & 0xff) || node->wn_flags != (flags & WN_MASK)
|| node->wn_prefixID != prefixID))) || node->wn_prefixID != prefixID)))
{ {
/* Allocate a new node. */ /* Allocate a new node. */
@ -4931,11 +4994,17 @@ put_node(fd, node, index, regionmask, prefixtree)
if (prefixtree) if (prefixtree)
{ {
/* In PREFIXTREE write the required prefixID and the /* In PREFIXTREE write the required prefixID and the
* associated condition nr (stored in wn_region). */ * associated condition nr (stored in wn_region). The
if (np->wn_flags == (char_u)-2) * byte value is misused to store the "rare" and "not
putc(BY_FLAGS, fd); /* <byte> rare */ * combining" flags */
if (np->wn_flags == (short_u)PFX_FLAGS_R)
putc(BY_FLAGS, fd); /* <byte> */
else if (np->wn_flags == (short_u)PFX_FLAGS_NC)
putc(BY_PFX_NC, fd);
else if (np->wn_flags == (short_u)PFX_FLAGS_RNC)
putc(BY_PFX_RNC, fd);
else else
putc(BY_NOFLAGS, fd); /* <byte> */ putc(BY_NOFLAGS, fd);
putc(np->wn_prefixID, fd); /* <prefixID> */ putc(np->wn_prefixID, fd); /* <prefixID> */
put_bytes(fd, (long_u)np->wn_region, 2); /* <prefcondnr> */ put_bytes(fd, (long_u)np->wn_region, 2); /* <prefcondnr> */
} }
@ -4954,8 +5023,17 @@ put_node(fd, node, index, regionmask, prefixtree)
} }
else else
{ {
putc(BY_FLAGS, fd); /* <byte> */ if (np->wn_flags >= 0x100)
putc(flags, fd); /* <flags> */ {
putc(BY_FLAGS2, fd); /* <byte> */
putc(flags, fd); /* <flags> */
putc((unsigned)flags >> 8, fd); /* <flags2> */
}
else
{
putc(BY_FLAGS, fd); /* <byte> */
putc(flags, fd); /* <flags> */
}
if (flags & WF_REGION) if (flags & WF_REGION)
putc(np->wn_region, fd); /* <region> */ putc(np->wn_region, fd); /* <region> */
if (flags & WF_PFX) if (flags & WF_PFX)
@ -5531,7 +5609,7 @@ clear_spell_chartab(sp)
* Called once while starting up and when 'encoding' changes. * Called once while starting up and when 'encoding' changes.
* The default is to use isalpha(), but the spell file should define the word * The default is to use isalpha(), but the spell file should define the word
* characters to make it possible that 'encoding' differs from the current * characters to make it possible that 'encoding' differs from the current
* locale. * locale. For utf-8 we don't use isalpha() but our own functions.
*/ */
void void
init_spell_chartab() init_spell_chartab()
@ -5774,9 +5852,10 @@ spell_iswordp(p, buf)
} }
} }
if (l > 1) c = mb_ptr2char(s);
if (c > 255)
return mb_get_class(s) >= 2; return mb_get_class(s) >= 2;
return spelltab.st_isw[*s]; return spelltab.st_isw[c];
} }
#endif #endif
@ -5792,10 +5871,16 @@ spell_iswordp_nmw(p)
char_u *p; char_u *p;
{ {
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
if (has_mbyte && MB_BYTE2LEN(*p) > 1) int c;
return mb_get_class(p) >= 2;
#endif
if (has_mbyte)
{
c = mb_ptr2char(p);
if (c > 255)
return mb_get_class(p) >= 2;
return spelltab.st_isw[c];
}
#endif
return spelltab.st_isw[*p]; return spelltab.st_isw[*p];
} }
@ -5818,7 +5903,7 @@ spell_iswordp_w(p, buf)
else else
s = p; s = p;
if (mb_char2len(*s) > 1) if (*s > 255)
{ {
if (enc_utf8) if (enc_utf8)
return utf_class(*s) >= 2; return utf_class(*s) >= 2;
@ -6035,13 +6120,13 @@ spell_suggest()
line = ml_get_curline(); line = ml_get_curline();
p = line + curwin->w_cursor.col; p = line + curwin->w_cursor.col;
/* Backup to before start of word. */ /* Backup to before start of word. */
while (p > line && SPELL_ISWORDP(p)) while (p > line && spell_iswordp_nmw(p))
mb_ptr_back(line, p); mb_ptr_back(line, p);
/* Forward to start of word. */ /* Forward to start of word. */
while (*p != NUL && !SPELL_ISWORDP(p)) while (*p != NUL && !spell_iswordp_nmw(p))
mb_ptr_adv(p); mb_ptr_adv(p);
if (!SPELL_ISWORDP(p)) /* No word found. */ if (!spell_iswordp_nmw(p)) /* No word found. */
{ {
beep_flush(); beep_flush();
return; return;
@ -6089,7 +6174,7 @@ spell_suggest()
for (;;) for (;;)
{ {
mb_ptr_back(line, p); mb_ptr_back(line, p);
if (p == line || SPELL_ISWORDP(p)) if (p == line || spell_iswordp_nmw(p))
break; break;
if (vim_regexec(&regmatch, p, 0) if (vim_regexec(&regmatch, p, 0)
&& regmatch.endp[0] == line + endcol) && regmatch.endp[0] == line + endcol)
@ -6731,7 +6816,7 @@ suggest_try_change(su)
idx_T *idxs, *fidxs, *pidxs; idx_T *idxs, *fidxs, *pidxs;
int depth; int depth;
int c, c2, c3; int c, c2, c3;
int n = 0; int n;
int flags; int flags;
garray_T *gap; garray_T *gap;
idx_T arridx; idx_T arridx;
@ -6822,11 +6907,14 @@ suggest_try_change(su)
; ;
sp->ts_curi += n; sp->ts_curi += n;
/* Always past NUL bytes now. */
n = (int)sp->ts_state;
sp->ts_state = STATE_ENDNUL;
/* At end of a prefix or at start of prefixtree: check for /* At end of a prefix or at start of prefixtree: check for
* following word. */ * following word. */
if (byts[arridx] == 0 || sp->ts_state == STATE_NOPREFIX) if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX)
{ {
sp->ts_state = STATE_START;
++depth; ++depth;
stack[depth] = stack[depth - 1]; stack[depth] = stack[depth - 1];
sp = &stack[depth]; sp = &stack[depth];
@ -6841,11 +6929,7 @@ suggest_try_change(su)
* find_keepcap_word() works. */ * find_keepcap_word() works. */
prewordlen = splitoff = sp->ts_twordlen; prewordlen = splitoff = sp->ts_twordlen;
mch_memmove(preword, tword, splitoff); mch_memmove(preword, tword, splitoff);
break;
} }
/* Always past NUL bytes now. */
sp->ts_state = STATE_ENDNUL;
break; break;
} }
@ -6876,8 +6960,9 @@ suggest_try_change(su)
; ;
if (c > 0) if (c > 0)
{ {
/* The prefix ID is stored two bytes above the flags. */ /* The prefix ID is stored three bytes above the
c = valid_word_prefix(c, n, (unsigned)flags >> 16, * flags. */
c = valid_word_prefix(c, n, flags,
tword + splitoff, lp->lp_slang); tword + splitoff, lp->lp_slang);
if (c == 0) if (c == 0)
break; break;
@ -6928,7 +7013,7 @@ suggest_try_change(su)
newscore = 0; newscore = 0;
if ((flags & WF_REGION) if ((flags & WF_REGION)
&& (((unsigned)flags >> 8) & lp->lp_region) == 0) && (((unsigned)flags >> 16) & lp->lp_region) == 0)
newscore += SCORE_REGION; newscore += SCORE_REGION;
if (flags & WF_RARE) if (flags & WF_RARE)
newscore += SCORE_RARE; newscore += SCORE_RARE;
@ -9735,7 +9820,7 @@ ex_spelldump(eap)
if ((round == 2 || (flags & WF_KEEPCAP) == 0) if ((round == 2 || (flags & WF_KEEPCAP) == 0)
&& (do_region && (do_region
|| (flags & WF_REGION) == 0 || (flags & WF_REGION) == 0
|| (((unsigned)flags >> 8) || (((unsigned)flags >> 16)
& lp->lp_region) != 0)) & lp->lp_region) != 0))
{ {
word[depth] = NUL; word[depth] = NUL;
@ -9744,7 +9829,7 @@ ex_spelldump(eap)
/* Dump the basic word if there is no prefix or /* Dump the basic word if there is no prefix or
* when it's the first one. */ * when it's the first one. */
c = (unsigned)flags >> 16; c = (unsigned)flags >> 24;
if (c == 0 || curi[depth] == 2) if (c == 0 || curi[depth] == 2)
dump_word(word, round, flags, lnum++); dump_word(word, round, flags, lnum++);
@ -9816,7 +9901,7 @@ dump_word(word, round, flags, lnum)
STRCAT(badword, "?"); STRCAT(badword, "?");
if (flags & WF_REGION) if (flags & WF_REGION)
for (i = 0; i < 7; ++i) for (i = 0; i < 7; ++i)
if (flags & (0x100 << i)) if (flags & (0x10000 << i))
sprintf((char *)badword + STRLEN(badword), "%d", i + 1); sprintf((char *)badword + STRLEN(badword), "%d", i + 1);
p = badword; p = badword;
} }
@ -9847,7 +9932,6 @@ apply_prefixes(slang, word, round, flags, startlnum)
int depth; int depth;
int n; int n;
int len; int len;
int prefid = (unsigned)flags >> 16;
int i; int i;
byts = slang->sl_pbyts; byts = slang->sl_pbyts;
@ -9856,15 +9940,16 @@ apply_prefixes(slang, word, round, flags, startlnum)
{ {
/* /*
* Loop over all prefixes, building them byte-by-byte in prefix[]. * Loop over all prefixes, building them byte-by-byte in prefix[].
* When at the end of a prefix check that it supports "prefid". * When at the end of a prefix check that it supports "flags".
*/ */
depth = 0; depth = 0;
arridx[0] = 0; arridx[0] = 0;
curi[0] = 1; curi[0] = 1;
while (depth >= 0 && !got_int) while (depth >= 0 && !got_int)
{ {
len = arridx[depth]; n = arridx[depth];
if (curi[depth] > byts[len]) len = byts[n];
if (curi[depth] > len)
{ {
/* Done all bytes at this node, go up one level. */ /* Done all bytes at this node, go up one level. */
--depth; --depth;
@ -9873,7 +9958,7 @@ apply_prefixes(slang, word, round, flags, startlnum)
else else
{ {
/* Do one more byte at this node. */ /* Do one more byte at this node. */
n = len + curi[depth]; n += curi[depth];
++curi[depth]; ++curi[depth];
c = byts[n]; c = byts[n];
if (c == 0) if (c == 0)
@ -9884,7 +9969,7 @@ apply_prefixes(slang, word, round, flags, startlnum)
break; break;
curi[depth] += i - 1; curi[depth] += i - 1;
i = valid_word_prefix(i, n, prefid, word, slang); i = valid_word_prefix(i, n, flags, word, slang);
if (i != 0) if (i != 0)
{ {
vim_strncpy(prefix + depth, word, MAXWLEN - depth - 1); vim_strncpy(prefix + depth, word, MAXWLEN - depth - 1);