diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-09-27 12:41:56 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-09-27 12:41:56 +0200 |
commit | 46a426c9acfdd3d6c0fa134a17681634b9325bee (patch) | |
tree | 04524eaade951e753e388a890c287a4373683fb0 | |
parent | d2842ea60bd608b7f9ec93c77d3f36a8e3bf5fe9 (diff) |
patch 8.1.2081: the spell.c file is too bigv8.1.2081
Problem: The spell.c file is too big.
Solution: Move the code for spell suggestions to a separate file. (Yegappan
Lakshmanan, closes #4988)
-rw-r--r-- | Filelist | 2 | ||||
-rw-r--r-- | src/Make_cyg_ming.mak | 1 | ||||
-rw-r--r-- | src/Make_morph.mak | 1 | ||||
-rw-r--r-- | src/Make_mvc.mak | 4 | ||||
-rw-r--r-- | src/Make_vms.mms | 10 | ||||
-rw-r--r-- | src/Makefile | 10 | ||||
-rw-r--r-- | src/README.md | 4 | ||||
-rw-r--r-- | src/proto.h | 1 | ||||
-rw-r--r-- | src/proto/spell.pro | 15 | ||||
-rw-r--r-- | src/proto/spellsuggest.pro | 5 | ||||
-rw-r--r-- | src/spell.c | 4554 | ||||
-rw-r--r-- | src/spell.h | 16 | ||||
-rw-r--r-- | src/spellsuggest.c | 4452 | ||||
-rw-r--r-- | src/version.c | 2 |
14 files changed, 4529 insertions, 4548 deletions
@@ -111,6 +111,7 @@ SRC_ALL = \ src/spell.c \ src/spell.h \ src/spellfile.c \ + src/spellsuggest.c \ src/structs.h \ src/syntax.c \ src/tag.c \ @@ -255,6 +256,7 @@ SRC_ALL = \ src/proto/sound.pro \ src/proto/spell.pro \ src/proto/spellfile.pro \ + src/proto/spellsuggest.pro \ src/proto/syntax.pro \ src/proto/tag.pro \ src/proto/term.pro \ diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 3bc57aa44c..521ec3a35e 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -778,6 +778,7 @@ OBJ = \ $(OUTDIR)/sign.o \ $(OUTDIR)/spell.o \ $(OUTDIR)/spellfile.o \ + $(OUTDIR)/spellsuggest.o \ $(OUTDIR)/syntax.o \ $(OUTDIR)/tag.o \ $(OUTDIR)/term.o \ diff --git a/src/Make_morph.mak b/src/Make_morph.mak index 0f3cd4ebfd..9c070c8e26 100644 --- a/src/Make_morph.mak +++ b/src/Make_morph.mak @@ -94,6 +94,7 @@ SRC = arabic.c \ sign.c \ spell.c \ spellfile.c \ + spellsuggest.c \ syntax.c \ tag.c \ term.c \ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index 3ad3547c1e..9146c7934e 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -785,6 +785,7 @@ OBJ = \ $(OUTDIR)\sign.obj \ $(OUTDIR)\spell.obj \ $(OUTDIR)\spellfile.obj \ + $(OUTDIR)\spellsuggest.obj \ $(OUTDIR)\syntax.obj \ $(OUTDIR)\tag.obj \ $(OUTDIR)\term.obj \ @@ -1670,6 +1671,8 @@ $(OUTDIR)/spell.obj: $(OUTDIR) spell.c $(INCL) $(OUTDIR)/spellfile.obj: $(OUTDIR) spellfile.c $(INCL) +$(OUTDIR)/spellsuggest.obj: $(OUTDIR) spellsuggest.c $(INCL) + $(OUTDIR)/syntax.obj: $(OUTDIR) syntax.c $(INCL) $(OUTDIR)/tag.obj: $(OUTDIR) tag.c $(INCL) @@ -1852,6 +1855,7 @@ proto.h: \ proto/sign.pro \ proto/spell.pro \ proto/spellfile.pro \ + proto/spellsuggest.pro \ proto/syntax.pro \ proto/tag.pro \ proto/term.pro \ diff --git a/src/Make_vms.mms b/src/Make_vms.mms index b8e5085bb6..3b45b7885a 100644 --- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -320,7 +320,8 @@ SRC = arabic.c arglist.c autocmd.c beval.c blob.c blowfish.c buffer.c \ ops.c \ option.c optionstr.c popupmnu.c popupwin.c profiler.c quickfix.c \ regexp.c register.c scriptfile.c \ - search.c session.c sha256.c sign.c spell.c spellfile.c syntax.c tag.c \ + search.c session.c sha256.c sign.c spell.c spellfile.c spellsuggest.c \ + syntax.c tag.c \ term.c termlib.c testing.c textprop.c ui.c undo.c usercmd.c \ userfunc.c version.c viminfo.c screen.c window.c os_unix.c os_vms.c \ pathdef.c \ @@ -342,7 +343,8 @@ OBJ = arabic.obj arglist.obj autocmd.obj beval.obj blob.obj blowfish.obj \ optionstr.obj popupmnu.obj popupwin.obj profiler.obj quickfix.obj \ regexp.obj register.obj scriptfile.obj \ search.obj session.obj sha256.obj sign.obj spell.obj spellfile.obj \ - syntax.obj tag.obj term.obj termlib.obj testing.obj textprop.obj \ + spellsuggest.obj syntax.obj tag.obj term.obj termlib.obj testing.obj \ + textprop.obj \ ui.obj undo.obj usercmd.obj userfunc.obj screen.obj version.obj \ viminfo.obj window.obj os_unix.obj os_vms.obj pathdef.obj if_mzsch.obj \ $(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \ @@ -791,6 +793,10 @@ spellfile.obj : spellfile.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h option.h structs.h \ regexp.h gui.h beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h \ proto.h globals.h +spellsuggest.obj : spellsuggest.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h option.h structs.h \ + regexp.h gui.h beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h \ + proto.h globals.h syntax.obj : syntax.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ diff --git a/src/Makefile b/src/Makefile index 9462404adf..0f949a8912 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1654,6 +1654,7 @@ BASIC_SRC = \ sound.c \ spell.c \ spellfile.c \ + spellsuggest.c \ syntax.c \ tag.c \ term.c \ @@ -1789,6 +1790,7 @@ OBJ_COMMON = \ objects/sound.o \ objects/spell.o \ objects/spellfile.o \ + objects/spellsuggest.o \ objects/syntax.o \ objects/tag.o \ objects/term.o \ @@ -1949,6 +1951,7 @@ PRO_AUTO = \ sound.pro \ spell.pro \ spellfile.pro \ + spellsuggest.pro \ syntax.pro \ tag.pro \ term.pro \ @@ -3386,6 +3389,9 @@ objects/spell.o: spell.c objects/spellfile.o: spellfile.c $(CCC) -o $@ spellfile.c +objects/spellsuggest.o: spellsuggest.c + $(CCC) -o $@ spellsuggest.c + objects/syntax.o: syntax.c $(CCC) -o $@ syntax.c @@ -3881,6 +3887,10 @@ objects/spellfile.o: spellfile.c vim.h protodef.h auto/config.h feature.h \ os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/spellsuggest.o: spellsuggest.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/syntax.o: syntax.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/README.md b/src/README.md index b5ee8b5718..b08f0b4931 100644 --- a/src/README.md +++ b/src/README.md @@ -69,7 +69,9 @@ screen.c | lower level screen functions search.c | pattern searching session.c | sessions and views sign.c | signs -spell.c | spell checking +spell.c | spell checking core +spellfile.c | spell file handling +spellsuggest.c | spell correction suggestions syntax.c | syntax and other highlighting tag.c | tags term.c | terminal handling, termcap codes diff --git a/src/proto.h b/src/proto.h index ae4c63a1c7..6d3b83deab 100644 --- a/src/proto.h +++ b/src/proto.h @@ -202,6 +202,7 @@ void qsort(void *base, size_t elm_count, size_t elm_size, int (*cmp)(const void # include "sound.pro" # include "spell.pro" # include "spellfile.pro" +# include "spellsuggest.pro" # include "syntax.pro" # include "tag.pro" # include "term.pro" diff --git a/src/proto/spell.pro b/src/proto/spell.pro index 6114412585..461b5e10ea 100644 --- a/src/proto/spell.pro +++ b/src/proto/spell.pro @@ -1,5 +1,11 @@ /* spell.c */ int spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, int docount); +int match_checkcompoundpattern(char_u *ptr, int wlen, garray_T *gap); +int can_compound(slang_T *slang, char_u *word, char_u *flags); +int match_compoundrule(slang_T *slang, char_u *compflags); +int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req); +int spell_valid_case(int wordflags, int treeflags); +int no_spell_checking(win_T *wp); int spell_move_to(win_T *wp, int dir, int allwords, int curline, hlf_T *attrp); void spell_cat_line(char_u *buf, char_u *line, int maxlen); char_u *spell_enc(void); @@ -19,12 +25,15 @@ buf_T *open_spellbuf(void); void close_spellbuf(buf_T *buf); void clear_spell_chartab(spelltab_T *sp); void init_spell_chartab(void); +int spell_iswordp(char_u *p, win_T *wp); +int spell_iswordp_nmw(char_u *p, win_T *wp); int spell_casefold(char_u *str, int len, char_u *buf, int buflen); -int spell_check_sps(void); -void spell_suggest(int count); +int check_need_cap(linenr_T lnum, colnr_T col); void ex_spellrepall(exarg_T *eap); -void spell_suggest_list(garray_T *gap, char_u *word, int maxcount, int need_cap, int interactive); void onecap_copy(char_u *word, char_u *wcopy, int upper); +void allcap_copy(char_u *word, char_u *wcopy); +int nofold_len(char_u *fword, int flen, char_u *word); +void make_case_word(char_u *fword, char_u *cword, int flags); char_u *eval_soundfold(char_u *word); void spell_soundfold(slang_T *slang, char_u *inword, int folded, char_u *res); void ex_spellinfo(exarg_T *eap); diff --git a/src/proto/spellsuggest.pro b/src/proto/spellsuggest.pro new file mode 100644 index 0000000000..745d407764 --- /dev/null +++ b/src/proto/spellsuggest.pro @@ -0,0 +1,5 @@ +/* spellsuggest.c */ +int spell_check_sps(void); +void spell_suggest(int count); +void spell_suggest_list(garray_T *gap, char_u *word, int maxcount, int need_cap, int interactive); +/* vim: set ft=c : */ diff --git a/src/spell.c b/src/spell.c index 4f4959e301..de478a3ed0 100644 --- a/src/spell.c +++ b/src/spell.c @@ -55,22 +55,6 @@ * See ":help develop-spell". */ -/* - * Use this to adjust the score after finding suggestions, based on the - * suggested word sounding like the bad word. This is much faster than doing - * it for every possible suggestion. - * Disadvantage: When "the" is typed as "hte" it sounds quite different ("@" - * vs "ht") and goes down in the list. - * Used when 'spellsuggest' is set to "best". - */ -#define RESCORE(word_score, sound_score) ((3 * word_score + sound_score) / 4) - -/* - * Do the opposite: based on a maximum end score and a known sound score, - * compute the maximum word score that can be used. - */ -#define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3) - #define IN_SPELL_C #include "vim.h" @@ -80,11 +64,6 @@ # include <time.h> /* for time_t */ #endif -/* only used for su_badflags */ -#define WF_MIXCAP 0x20 /* mix of upper and lower case: macaRONI */ - -#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP) - #define REGION_ALL 0xff /* word valid in all regions */ #define VIMSUGMAGIC "VIMsug" /* string at start of Vim .sug file */ @@ -98,109 +77,6 @@ #define SP_LOCAL 2 #define SP_BAD 3 -typedef struct wordcount_S -{ - short_u wc_count; /* nr of times word was seen */ - char_u wc_word[1]; /* word, actually longer */ -} wordcount_T; - -#define WC_KEY_OFF offsetof(wordcount_T, wc_word) -#define HI2WC(hi) ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF)) -#define MAXWORDCOUNT 0xffff - -/* - * Information used when looking for suggestions. - */ -typedef struct suginfo_S -{ - garray_T su_ga; /* suggestions, contains "suggest_T" */ - int su_maxcount; /* max. number of suggestions displayed */ - int su_maxscore; /* maximum score for adding to su_ga */ - int su_sfmaxscore; /* idem, for when doing soundfold words */ - garray_T su_sga; /* like su_ga, sound-folded scoring */ - char_u *su_badptr; /* start of bad word in line */ - int su_badlen; /* length of detected bad word in line */ - int su_badflags; /* caps flags for bad word */ - char_u su_badword[MAXWLEN]; /* bad word truncated at su_badlen */ - char_u su_fbadword[MAXWLEN]; /* su_badword case-folded */ - char_u su_sal_badword[MAXWLEN]; /* su_badword soundfolded */ - hashtab_T su_banned; /* table with banned words */ - slang_T *su_sallang; /* default language for sound folding */ -} suginfo_T; - -/* One word suggestion. Used in "si_ga". */ -typedef struct suggest_S -{ - char_u *st_word; /* suggested word, allocated string */ - int st_wordlen; /* STRLEN(st_word) */ - int st_orglen; /* length of replaced text */ - int st_score; /* lower is better */ - int st_altscore; /* used when st_score compares equal */ - int st_salscore; /* st_score is for soundalike */ - int st_had_bonus; /* bonus already included in score */ - slang_T *st_slang; /* language used for sound folding */ -} suggest_T; - -#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i]) - -/* TRUE if a word appears in the list of banned words. */ -#define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word))) - -/* Number of suggestions kept when cleaning up. We need to keep more than - * what is displayed, because when rescore_suggestions() is called the score - * may change and wrong suggestions may be removed later. */ -#define SUG_CLEAN_COUNT(su) ((su)->su_maxcount < 130 ? 150 : (su)->su_maxcount + 20) - -/* Threshold for sorting and cleaning up suggestions. Don't want to keep lots - * of suggestions that are not going to be displayed. */ -#define SUG_MAX_COUNT(su) (SUG_CLEAN_COUNT(su) + 50) - -/* score for various changes */ -#define SCORE_SPLIT 149 /* split bad word */ -#define SCORE_SPLIT_NO 249 /* split bad word with NOSPLITSUGS */ -#define SCORE_ICASE 52 /* slightly different case */ -#define SCORE_REGION 200 /* word is for different region */ -#define SCORE_RARE 180 /* rare word */ -#define SCORE_SWAP 75 /* swap two characters */ -#define SCORE_SWAP3 110 /* swap two characters in three */ -#define SCORE_REP 65 /* REP replacement */ -#define SCORE_SUBST 93 /* substitute a character */ -#define SCORE_SIMILAR 33 /* substitute a similar character */ -#define SCORE_SUBCOMP 33 /* substitute a composing character */ -#define SCORE_DEL 94 /* delete a character */ -#define SCORE_DELDUP 66 /* delete a duplicated character */ -#define SCORE_DELCOMP 28 /* delete a composing character */ -#define SCORE_INS 96 /* insert a character */ -#define SCORE_INSDUP 67 /* insert a duplicate character */ -#define SCORE_INSCOMP 30 /* insert a composing character */ -#define SCORE_NONWORD 103 /* change non-word to word char */ - -#define SCORE_FILE 30 /* suggestion from a file */ -#define SCORE_MAXINIT 350 /* Initial maximum score: higher == slower. - * 350 allows for about three changes. */ - -#define SCORE_COMMON1 30 /* subtracted for words seen before */ -#define SCORE_COMMON2 40 /* subtracted for words often seen */ -#define SCORE_COMMON3 50 /* subtracted for words very often seen */ -#define SCORE_THRES2 10 /* word count threshold for COMMON2 */ -#define SCORE_THRES3 100 /* word count threshold for COMMON3 */ - -/* When trying changed soundfold words it becomes slow when trying more than - * two changes. With less then two changes it's slightly faster but we miss a - * few good suggestions. In rare cases we need to try three of four changes. - */ -#define SCORE_SFMAX1 200 /* maximum score for first try */ -#define SCORE_SFMAX2 300 /* maximum score for second try */ -#define SCORE_SFMAX3 400 /* maximum score for third try */ - -#define SCORE_BIG SCORE_INS * 3 /* big difference */ -#define SCORE_MAXMAX 999999 /* accept any score */ -#define SCORE_LIMITMAX 350 /* for spell_edit_score_limit() */ - -/* for spell_edit_score_limit() we need to know the minimum value of - * SCORE_ICASE, SCORE_SWAP, SCORE_DEL, SCORE_SIMILAR and SCORE_INS */ -#define SCORE_EDIT_MIN SCORE_SIMILAR - /* * Structure to store info for word matching. */ @@ -244,80 +120,8 @@ typedef struct matchinf_S } matchinf_T; -static int spell_iswordp(char_u *p, win_T *wp); static int spell_mb_isword_class(int cl, win_T *wp); -/* - * For finding suggestions: At each node in the tree these states are tried: - */ -typedef enum -{ - STATE_START = 0, /* At start of node check for NUL bytes (goodword - * ends); if badword ends there is a match, otherwise - * try splitting word. */ - STATE_NOPREFIX, /* try without prefix */ - STATE_SPLITUNDO, /* Undo splitting. */ - STATE_ENDNUL, /* Past NUL bytes at start of the node. */ - STATE_PLAIN, /* Use each byte of the node. */ - STATE_DEL, /* Delete a byte from the bad word. */ - STATE_INS_PREP, /* Prepare for inserting bytes. */ - STATE_INS, /* Insert a byte in the bad word. */ - STATE_SWAP, /* Swap two bytes. */ - STATE_UNSWAP, /* Undo swap two characters. */ - STATE_SWAP3, /* Swap two characters over three. */ - STATE_UNSWAP3, /* Undo Swap two characters over three. */ - STATE_UNROT3L, /* Undo rotate three characters left */ - STATE_UNROT3R, /* Undo rotate three characters right */ - STATE_REP_INI, /* Prepare for using REP items. */ - STATE_REP, /* Use matching REP items from the .aff file. */ - STATE_REP_UNDO, /* Undo a REP item replacement. */ - STATE_FINAL /* End of this node. */ -} state_T; - -/* - * Struct to keep the state at each level in suggest_try_change(). - */ -typedef struct trystate_S -{ - state_T ts_state; /* state at this level, STATE_ */ - int ts_score; /* score */ - idx_T ts_arridx; /* index in tree array, start of node */ - short ts_curi; /* index in list of child nodes */ - char_u ts_fidx; /* index in fword[], case-folded bad word */ - char_u ts_fidxtry; /* ts_fidx at which bytes may be changed */ - char_u ts_twordlen; /* valid length of tword[] */ - char_u ts_prefixdepth; /* stack depth for end of prefix or - * PFD_PREFIXTREE or PFD_NOPREFIX */ - char_u ts_flags; /* TSF_ flags */ - char_u ts_tcharlen; /* number of bytes in tword character */ - char_u ts_tcharidx; /* current byte index in tword character */ - char_u ts_isdiff; /* DIFF_ values */ - char_u ts_fcharstart; /* index in fword where badword char started */ - char_u ts_prewordlen; /* length of word in "preword[]" */ - char_u ts_splitoff; /* index in "tword" after last split */ - char_u ts_splitfidx; /* "ts_fidx" at word split */ - char_u ts_complen; /* nr of compound words used */ - char_u ts_compsplit; /* index for "compflags" where word was spit */ - char_u ts_save_badflags; /* su_badflags saved here */ - char_u ts_delidx; /* index in fword for char that was deleted, - valid when "ts_flags" has TSF_DIDDEL */ -} trystate_T; - -/* values for ts_isdiff */ -#define DIFF_NONE 0 /* no different byte (yet) */ -#define DIFF_YES 1 /* different byte found */ -#define DIFF_INSERT 2 /* inserting character */ - -/* values for ts_flags */ -#define TSF_PREFIXOK 1 /* already checked that prefix is OK */ -#define TSF_DIDSPLIT 2 /* tried split at this point */ -#define TSF_DIDDEL 4 /* did a delete, "ts_delidx" has index */ - -/* special values ts_prefixdepth */ -#define PFD_NOPREFIX 0xff /* not using prefixes */ -#define PFD_PREFIXTREE 0xfe /* walking through the prefix tree */ -#define PFD_NOTSPECIAL 0xfd /* highest value that's not special */ - /* mode values for find_word */ #define FIND_FOLDWORD 0 /* find word case-folded */ #define FIND_KEEPWORD 1 /* find keep-case word */ @@ -326,64 +130,19 @@ typedef struct trystate_S #define FIND_KEEPCOMPOUND 4 /* find keep-case compound word */ static void find_word(matchinf_T *mip, int mode); -static int match_checkcompoundpattern(char_u *ptr, int wlen, garray_T *gap); -static int can_compound(slang_T *slang, char_u *word, char_u *flags); -static int match_compoundrule(slang_T *slang, char_u *compflags); -static int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req); static void find_prefix(matchinf_T *mip, int mode); static int fold_more(matchinf_T *mip); -static int spell_valid_case(int wordflags, int treeflags); static void spell_load_cb(char_u *fname, void *cookie); static int count_syllables(slang_T *slang, char_u *word); static void clear_midword(win_T *buf); static void use_midword(slang_T *lp, win_T *buf); static int find_region(char_u *rp, char_u *region); -static int spell_iswordp_nmw(char_u *p, win_T *wp); -static int check_need_cap(linenr_T lnum, colnr_T col); -static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int maxcount, int banbadword, int need_cap, int interactive); -#ifdef FEAT_EVAL -static void spell_suggest_expr(suginfo_T *su, char_u *expr); -#endif -static void spell_suggest_file(suginfo_T *su, char_u *fname); -static void spell_suggest_intern(suginfo_T *su, int interactive); -static void spell_find_cleanup(suginfo_T *su); -static void suggest_try_special(suginfo_T *su); -static void suggest_try_change(suginfo_T *su); -static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, int soundfold); -static void go_deeper(trystate_T *stack, int depth, int score_add); -static int nofold_len(char_u *fword, int flen, char_u *word); -static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword); -static void score_comp_sal(suginfo_T *su); -static void score_combine(suginfo_T *su); -static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *badsound); -static void suggest_try_soundalike_prep(void); -static void suggest_try_soundalike(suginfo_T *su); -static void suggest_try_soundalike_finish(void); -static void add_sound_suggest(suginfo_T *su, char_u *goodword, int score, langp_T *lp); -static int soundfold_find(slang_T *slang, char_u *word); -static void make_case_word(char_u *fword, char_u *cword, int flags); -static int similar_chars(slang_T *slang, int c1, int c2); -static void add_suggestion(suginfo_T *su, garray_T *gap, char_u *goodword, int badlen, int score, int altscore, int had_bonus, slang_T *slang, int maxsf); -static void check_suggestions(suginfo_T *su, garray_T *gap); -static void add_banned(suginfo_T *su, char_u *word); -static void rescore_suggestions(suginfo_T *su); -static void rescore_one(suginfo_T *su, suggest_T *stp); -static int cleanup_suggestions(garray_T *gap, int maxscore, int keep); static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res); static void spell_soundfold_sal(slang_T *slang, char_u *inword, char_u *res); static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res); -static int soundalike_score(char_u *goodsound, char_u *badsound); -static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword); -static int spell_edit_score_limit(slang_T *slang, char_u *badword, char_u *goodword, int limit); -static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goodword, int limit); static void dump_word(slang_T *slang, char_u *word, char_u *pat, int *dir, int round, int flags, linenr_T lnum); static linenr_T dump_prefixes(slang_T *slang, char_u *word, char_u *pat, int *dir, int round, int flags, linenr_T startlnum); - -/* Remember what "z?" replaced. */ -static char_u *repl_from = NULL; -static char_u *repl_to = NULL; - /* * Main spell-checking function. * "ptr" points to a character that could be the start of a word. @@ -1125,7 +884,7 @@ find_word(matchinf_T *mip, int mode) * A match means that the first part of CHECKCOMPOUNDPATTERN matches at the * end of ptr[wlen] and the second part matches after it. */ - static int + int match_checkcompoundpattern( char_u *ptr, int wlen, @@ -1155,7 +914,7 @@ match_checkcompoundpattern( * Return TRUE if "flags" is a valid sequence of compound flags and "word" * does not have too many syllables. */ - static int + int can_compound(slang_T *slang, char_u *word, char_u *flags) { char_u uflags[MAXWLEN * 2]; @@ -1188,48 +947,12 @@ can_compound(slang_T *slang, char_u *word, char_u *flags) } /* - * Return TRUE when the sequence of flags in "compflags" plus "flag" can - * possibly form a valid compounded word. This also checks the COMPOUNDRULE - * lines if they don't contain wildcards. - */ - static int -can_be_compound( - trystate_T *sp, - slang_T *slang, - char_u *compflags, - int flag) -{ - /* If the flag doesn't appear in sl_compstartflags or sl_compallflags - * then it can't possibly compound. */ - if (!byte_in_str(sp->ts_complen == sp->ts_compsplit - ? slang->sl_compstartflags : slang->sl_compallflags, flag)) - return FALSE; - - /* If there are no wildcards, we can check if the flags collected so far - * possibly can form a match with COMPOUNDRULE patterns. This only - * makes sense when we have two or more words. */ - if (slang->sl_comprules != NULL && sp->ts_complen > sp->ts_compsplit) - { - int v; - - compflags[sp->ts_complen] = flag; - compflags[sp->ts_complen + 1] = NUL; - v = match_compoundrule(slang, compflags + sp->ts_compsplit); - compflags[sp->ts_complen] = NUL; - return v; - } - - return TRUE; -} - - -/* * Return TRUE if the compound flags in compflags[] match the start of any * 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. */ - static int + int match_compoundrule(slang_T *slang, char_u *compflags) { char_u *p; @@ -1282,7 +1005,7 @@ match_compoundrule(slang_T *slang, char_u *compflags) * ID in "flags" for the word "word". * The WF_RAREPFX flag is included in the return value for a rare prefix. */ - static int + int valid_word_prefix( int totprefcnt, /* nr of prefix IDs */ int arridx, /* idx in sl_pidxs[] */ @@ -1482,7 +1205,7 @@ fold_more(matchinf_T *mip) * Check case flags for a word. Return TRUE if the word has the requested * case. */ - static int + int spell_valid_case( int wordflags, /* flags for the checked word. */ int treeflags) /* flags for the word in the spell tree */ @@ -1496,7 +1219,7 @@ spell_valid_case( /* * Return TRUE if spell checking is not enabled. */ - static int + int no_spell_checking(win_T *wp) { if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL @@ -2102,43 +1825,6 @@ count_common_word( } /* - * Adjust the score of common words. - */ - static int -score_wordcount_adj( - slang_T *slang, - int score, - char_u *word, - int split) /* word was split, less bonus */ -{ - hashitem_T *hi; - wordcount_T *wc; - int bonus; - int newscore; - - hi = hash_find(&slang->sl_wordcount, word); - if (!HASHITEM_EMPTY(hi)) - { - wc = HI2WC(hi); - if (wc->wc_count < SCORE_THRES2) - bonus = SCORE_COMMON1; - else if (wc->wc_count < SCORE_THRES3) - bonus = SCORE_COMMON2; - else - bonus = SCORE_COMMON3; - if (split) - newscore = score - bonus / 2; - else - newscore = score - bonus; - if (newscore < 0) - return 0; - return newscore; - } - return score; -} - - -/* * Return TRUE if byte "n" appears in "str". * Like strchr() but independent of locale. */ @@ -2712,53 +2398,6 @@ captype( } /* - * Like captype() but for a KEEPCAP word add ONECAP if the word starts with a - * capital. So that make_case_word() can turn WOrd into Word. - * Add ALLCAP for "WOrD". - */ - static int -badword_captype(char_u *word, char_u *end) -{ - int flags = captype(word, end); - int c; - int l, u; - int first; - char_u *p; - - if (flags & WF_KEEPCAP) - { - /* Count the number of UPPER and lower case letters. */ - l = u = 0; - first = FALSE; - for (p = word; p < end; MB_PTR_ADV(p)) - { - c = PTR2CHAR(p); - if (SPELL_ISUPPER(c)) - { - ++u; - if (p == word) - first = TRUE; - } - else - ++l; - } - - /* If there are more UPPER than lower case letters suggest an - * ALLCAP word. Otherwise, if the first letter is UPPER then - * suggest ONECAP. Exception: "ALl" most likely should be "All", - * require three upper case letters. */ - if (u > l && u > 2) - flags |= WF_ALLCAP; - else if (first) - flags |= WF_ONECAP; - - if (u >= 2 && l >= 2) /* maCARONI maCAroni */ - flags |= WF_MIXCAP; - } - return flags; -} - -/* * Delete the internal wordlist and its .spl file. */ void @@ -2833,47 +2472,6 @@ spell_reload(void) } /* - * Opposite of offset2bytes(). - * "pp" points to the bytes and is advanced over it. - * Returns the offset. - */ - static int -bytes2offset(char_u **pp) -{ - char_u *p = *pp; - int nr; - int c; - - c = *p++; - if ((c & 0x80) == 0x00) /* 1 byte */ - { - nr = c - 1; - } - else if ((c & 0xc0) == 0x80) /* 2 bytes */ - { - nr = (c & 0x3f) - 1; - nr = nr * 255 + (*p++ - 1); - } - else if ((c & 0xe0) == 0xc0) /* 3 bytes */ - { - nr = (c & 0x1f) - 1; - nr = nr * 255 + (*p++ - 1); - nr = nr * 255 + (*p++ - 1); - } - else /* 4 bytes */ - { - nr = (c & 0x0f) - 1; - nr = nr * 255 + (*p++ - 1); - nr = nr * 255 + (*p++ - 1); - nr = nr * 255 + (*p++ - 1); - } - - *pp = p; - return nr; -} - - -/* * Open a spell buffer. This is a nameless buffer that is not in the buffer * list and only contains text lines. Can use a swapfile to reduce memory * use. @@ -3012,7 +2610,7 @@ init_spell_chartab(void) * 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 + int spell_iswordp( char_u *p, win_T *wp) /* buffer used */ @@ -3053,7 +2651,7 @@ spell_iswordp( * Return TRUE if "p" points to a word character. * Unlike spell_iswordp() this doesn't check for "midword" characters. */ - static int + int spell_iswordp_nmw(char_u *p, win_T *wp) { int c; @@ -3162,313 +2760,11 @@ spell_casefold( return OK; } -/* values for sps_flags */ -#define SPS_BEST 1 -#define SPS_FAST 2 -#define SPS_DOUBLE 4 - -static int sps_flags = SPS_BEST; /* flags from 'spellsuggest' */ -static int sps_limit = 9999; /* max nr of suggestions given */ - -/* - * Check the 'spellsuggest' option. Return FAIL if it's wrong. - * Sets "sps_flags" and "sps_limit". - */ - int -spell_check_sps(void) -{ - char_u *p; - char_u *s; - char_u buf[MAXPATHL]; - int f; - - sps_flags = 0; - sps_limit = 9999; - - for (p = p_sps; *p != NUL; ) - { - copy_option_part(&p, buf, MAXPATHL, ","); - - f = 0; - if (VIM_ISDIGIT(*buf)) - { - s = buf; - sps_limit = getdigits(&s); - if (*s != NUL && !VIM_ISDIGIT(*s)) - f = -1; - } - else if (STRCMP(buf, "best") == 0) - f = SPS_BEST; - else if (STRCMP(buf, "fast") == 0) - f = SPS_FAST; - else if (STRCMP(buf, "double") == 0) - f = SPS_DOUBLE; - else if (STRNCMP(buf, "expr:", 5) != 0 - && STRNCMP(buf, "file:", 5) != 0) - f = -1; - - if (f == -1 || (sps_flags != 0 && f != 0)) - { - sps_flags = SPS_BEST; - sps_limit = 9999; - return FAIL; - } - if (f != 0) - sps_flags = f; - } - - if (sps_flags == 0) - sps_flags = SPS_BEST; - - return OK; -} - -/* - * "z=": Find badly spelled word under or after the cursor. - * Give suggestions for the properly spelled word. - * In Visual mode use the highlighted word as the bad word. - * When "count" is non-zero use that suggestion. - */ - void -spell_suggest(int count) -{ - char_u *line; - pos_T prev_cursor = curwin->w_cursor; - char_u wcopy[MAXWLEN + 2]; - char_u *p; - int i; - int c; - suginfo_T sug; - suggest_T *stp; - int mouse_used; - int need_cap; - int limit; - int selected = count; - int badlen = 0; - int msg_scroll_save = msg_scroll; - - if (no_spell_checking(curwin)) - return; - - if (VIsual_active) - { - /* Use the Visually selected text as the bad word. But reject - * a multi-line selection. */ - if (curwin->w_cursor.lnum != VIsual.lnum) - { - vim_beep(BO_SPELL); - return; - } - badlen = (int)curwin->w_cursor.col - (int)VIsual.col; - if (badlen < 0) - badlen = -badlen; - else - curwin->w_cursor.col = VIsual.col; - ++badlen; - end_visual_mode(); - } - /* Find the start of the badly spelled word. */ - else if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0 - || curwin->w_cursor.col > prev_cursor.col) - { - /* No bad word or it starts after the cursor: use the word under the - * cursor. */ - curwin->w_cursor = prev_cursor; - line = ml_get_curline(); - p = line + curwin->w_cursor.col; - /* Backup to before start of word. */ - while (p > line && spell_iswordp_nmw(p, curwin)) - MB_PTR_BACK(line, p); - /* Forward to start of word. */ - while (*p != NUL && !spell_iswordp_nmw(p, curwin)) - MB_PTR_ADV(p); - - if (!spell_iswordp_nmw(p, curwin)) /* No word found. */ - { - beep_flush(); - return; - } - curwin->w_cursor.col = (colnr_T)(p - line); - } - - /* Get the word and its length. */ - - /* Figure out if the word should be capitalised. */ - need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col); - - /* Make a copy of current line since autocommands may free the line. */ |