vim-patch:7.4.1064

Problem:    When a spell file has single letter compounding creating
            suggestions takes an awful long time.
Solution:   Add th eNOCOMPOUNDSUGS flag.

7b877b3605
This commit is contained in:
James McCoy
2016-05-24 21:14:37 -04:00
parent ca7e43100a
commit 3d12192521
3 changed files with 56 additions and 24 deletions

View File

@@ -1373,6 +1373,14 @@ the item name. Case is always ignored.
The Hunspell feature to use three arguments and flags is not supported. The Hunspell feature to use three arguments and flags is not supported.
*spell-NOCOMPOUNDSUGS*
This item indicates that using compounding to make suggestions is not a good
idea. Use this when compounding is used with very short or one-character
words. E.g. to make numbers out of digits. Without this flag creating
suggestions would spend most time trying all kind of weird compound words.
NOCOMPOUNDSUGS ~
*spell-SYLLABLE* *spell-SYLLABLE*
The SYLLABLE item defines characters or character sequences that are used to The SYLLABLE item defines characters or character sequences that are used to
count the number of syllables in a word. Example: count the number of syllables in a word. Example:

View File

@@ -45,6 +45,9 @@
// Use SPELL_PRINTTREE for debugging: dump the word tree after adding a word. // Use SPELL_PRINTTREE for debugging: dump the word tree after adding a word.
// Only use it for small word lists! // Only use it for small word lists!
// Use SPELL_COMPRESS_ALLWAYS for debugging: compress the word tree after
// adding a word. Only use it for small word lists!
// Use DEBUG_TRIEWALK to print the changes made in suggest_trie_walk() for a // Use DEBUG_TRIEWALK to print the changes made in suggest_trie_walk() for a
// specific word. // specific word.
@@ -156,6 +159,8 @@
// //
// sectionID == SN_NOSPLITSUGS: nothing // sectionID == SN_NOSPLITSUGS: nothing
// //
// sectionID == SN_NOCOMPOUNDSUGS: nothing
//
// sectionID == SN_WORDS: <word> ... // sectionID == SN_WORDS: <word> ...
// <word> N bytes NUL terminated common word // <word> N bytes NUL terminated common word
// //
@@ -482,7 +487,7 @@ struct slang_S {
regprog_T **sl_prefprog; // table with regprogs for prefixes regprog_T **sl_prefprog; // table with regprogs for prefixes
garray_T sl_rep; // list of fromto_T entries from REP lines garray_T sl_rep; // list of fromto_T entries from REP lines
short sl_rep_first[256]; // indexes where byte first appears, -1 if int16_t sl_rep_first[256]; // indexes where byte first appears, -1 if
// there is none // there is none
garray_T sl_sal; // list of salitem_T entries from SAL lines garray_T sl_sal; // list of salitem_T entries from SAL lines
salfirst_T sl_sal_first[256]; // indexes where byte first appears, -1 if salfirst_T sl_sal_first[256]; // indexes where byte first appears, -1 if
@@ -494,8 +499,9 @@ struct slang_S {
// "sl_sal_first" maps chars, when has_mbyte // "sl_sal_first" maps chars, when has_mbyte
// "sl_sal" is a list of wide char lists. // "sl_sal" is a list of wide char lists.
garray_T sl_repsal; // list of fromto_T entries from REPSAL lines garray_T sl_repsal; // list of fromto_T entries from REPSAL lines
short sl_repsal_first[256]; // sl_rep_first for REPSAL lines int16_t sl_repsal_first[256]; // sl_rep_first for REPSAL lines
bool sl_nosplitsugs; // don't suggest splitting a word bool sl_nosplitsugs; // don't suggest splitting a word
bool sl_nocompoundsugs; // don't suggest compounding
// Info from the .sug file. Loaded on demand. // Info from the .sug file. Loaded on demand.
time_t sl_sugtime; // timestamp for .sug file time_t sl_sugtime; // timestamp for .sug file
@@ -558,6 +564,7 @@ typedef struct langp_S {
#define SN_WORDS 13 // common words #define SN_WORDS 13 // common words
#define SN_NOSPLITSUGS 14 // don't split word for suggestions #define SN_NOSPLITSUGS 14 // don't split word for suggestions
#define SN_INFO 15 // info section #define SN_INFO 15 // info section
#define SN_NOCOMPOUNDSUGS 16 // don't compound for suggestions
#define SN_END 255 // end of sections #define SN_END 255 // end of sections
#define SNF_REQUIRED 1 // <sectionflags>: required section #define SNF_REQUIRED 1 // <sectionflags>: required section
@@ -948,6 +955,7 @@ typedef struct spellinfo_S {
char_u *si_sofoto; // SOFOTO text char_u *si_sofoto; // SOFOTO text
int si_nosugfile; // NOSUGFILE item found int si_nosugfile; // NOSUGFILE item found
int si_nosplitsugs; // NOSPLITSUGS item found int si_nosplitsugs; // NOSPLITSUGS item found
int si_nocompoundsugs; // NOCOMPOUNDSUGS item found
int si_followup; // soundsalike: ? int si_followup; // soundsalike: ?
int si_collapse; // soundsalike: ? int si_collapse; // soundsalike: ?
hashtab_T si_commonwords; // hashtable for common words hashtab_T si_commonwords; // hashtable for common words
@@ -2666,7 +2674,11 @@ spell_load_file (
break; break;
case SN_NOSPLITSUGS: case SN_NOSPLITSUGS:
lp->sl_nosplitsugs = true; // <timestamp> lp->sl_nosplitsugs = true;
break;
case SN_NOCOMPOUNDSUGS:
lp->sl_nocompoundsugs = true;
break; break;
case SN_COMPOUND: case SN_COMPOUND:
@@ -2868,7 +2880,7 @@ static int read_prefcond_section(FILE *fd, slang_T *lp)
// Read REP or REPSAL items section from "fd": <repcount> <rep> ... // Read REP or REPSAL items section from "fd": <repcount> <rep> ...
// Return SP_*ERROR flags. // Return SP_*ERROR flags.
static int read_rep_section(FILE *fd, garray_T *gap, short *first) static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
{ {
int cnt; int cnt;
fromto_T *ftp; fromto_T *ftp;
@@ -4266,9 +4278,9 @@ static void spell_print_node(wordnode_T *node, int depth)
PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0); PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0);
PRINTSOME(line2, depth, " ", 0, 0); PRINTSOME(line2, depth, " ", 0, 0);
PRINTSOME(line3, depth, " ", 0, 0); PRINTSOME(line3, depth, " ", 0, 0);
msg(line1); msg((char_u *)line1);
msg(line2); msg((char_u *)line2);
msg(line3); msg((char_u *)line3);
} else { } else {
node->wn_u1.index = TRUE; node->wn_u1.index = TRUE;
@@ -4289,9 +4301,9 @@ static void spell_print_node(wordnode_T *node, int depth)
PRINTSOME(line3, depth, " ", 0, 0); PRINTSOME(line3, depth, " ", 0, 0);
if (node->wn_byte == NUL) { if (node->wn_byte == NUL) {
msg(line1); msg((char_u *)line1);
msg(line2); msg((char_u *)line2);
msg(line3); msg((char_u *)line3);
} }
// do the children // do the children
@@ -4633,6 +4645,8 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
spin->si_nobreak = true; spin->si_nobreak = true;
} else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) { } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
spin->si_nosplitsugs = true; spin->si_nosplitsugs = true;
} else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) {
spin->si_nocompoundsugs = true;
} else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) { } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
spin->si_nosugfile = true; spin->si_nosugfile = true;
} else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) { } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
@@ -6289,7 +6303,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
node = *prev; node = *prev;
} }
#ifdef SPELL_PRINTTREE #ifdef SPELL_PRINTTREE
smsg("Added \"%s\"", word); smsg((char_u *)"Added \"%s\"", word);
spell_print_tree(root->wn_sibling); spell_print_tree(root->wn_sibling);
#endif #endif
@@ -6312,8 +6326,8 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
// 3. When compressed before, added "compress_added" words // 3. When compressed before, added "compress_added" words
// (si_compress_cnt == 1) and the number of free nodes drops below the // (si_compress_cnt == 1) and the number of free nodes drops below the
// maximum word length. // maximum word length.
#ifndef SPELL_PRINTTREE #ifndef SPELL_COMPRESS_ALLWAYS
if (spin->si_compress_cnt == 1 if (spin->si_compress_cnt == 1 // NOLINT(readability/braces)
? spin->si_free_count < MAXWLEN ? spin->si_free_count < MAXWLEN
: spin->si_blocks_cnt >= compress_start) : spin->si_blocks_cnt >= compress_start)
#endif #endif
@@ -6857,6 +6871,15 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
put_bytes(fd, 0, 4); // <sectionlen> put_bytes(fd, 0, 4); // <sectionlen>
} }
// SN_NOCOMPUNDSUGS: nothing
// This is used to notify that no suggestions with compounds are to be
// made.
if (spin->si_nocompoundsugs) {
putc(SN_NOCOMPOUNDSUGS, fd); // <sectionID>
putc(0, fd); // <sectionflags>
put_bytes(fd, 0, 4); // <sectionlen>
}
// SN_COMPOUND: compound info. // SN_COMPOUND: compound info.
// We don't mark it required, when not supported all compound words will // We don't mark it required, when not supported all compound words will
// be bad words. // be bad words.
@@ -9771,6 +9794,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// be possible to compound another (short) word. // be possible to compound another (short) word.
try_compound = false; try_compound = false;
if (!soundfold if (!soundfold
&& !slang->sl_nocompoundsugs
&& slang->sl_compprog != NULL && slang->sl_compprog != NULL
&& ((unsigned)flags >> 24) != 0 && ((unsigned)flags >> 24) != 0
&& sp->ts_twordlen - sp->ts_splitoff && sp->ts_twordlen - sp->ts_splitoff
@@ -9791,21 +9815,21 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// For NOBREAK we never try splitting, it won't make any word // For NOBREAK we never try splitting, it won't make any word
// valid. // valid.
if (slang->sl_nobreak) if (slang->sl_nobreak && !slang->sl_nocompoundsugs) {
try_compound = true; try_compound = true;
} else if (!fword_ends
&& try_compound
&& (sp->ts_flags & TSF_DIDSPLIT) == 0) {
// If we could add a compound word, and it's also possible to // If we could add a compound word, and it's also possible to
// split at this point, do the split first and set // split at this point, do the split first and set
// TSF_DIDSPLIT to avoid doing it again. // TSF_DIDSPLIT to avoid doing it again.
else if (!fword_ends
&& try_compound
&& (sp->ts_flags & TSF_DIDSPLIT) == 0) {
try_compound = false; try_compound = false;
sp->ts_flags |= TSF_DIDSPLIT; sp->ts_flags |= TSF_DIDSPLIT;
--sp->ts_curi; // do the same NUL again --sp->ts_curi; // do the same NUL again
compflags[sp->ts_complen] = NUL; compflags[sp->ts_complen] = NUL;
} else } else {
sp->ts_flags &= ~TSF_DIDSPLIT; sp->ts_flags &= ~TSF_DIDSPLIT;
}
if (try_split || try_compound) { if (try_split || try_compound) {
if (!try_compound && (!fword_ends || !goodword_ends)) { if (!try_compound && (!fword_ends || !goodword_ends)) {

View File

@@ -620,7 +620,7 @@ static int included_patches[] = {
// 1067 NA // 1067 NA
// 1066 NA // 1066 NA
1065, 1065,
// 1064, 1064,
// 1063 NA // 1063 NA
// 1062 NA // 1062 NA
1061, 1061,