Data Structures | Macros | Typedefs | Functions | Variables
spell.c File Reference
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <wctype.h>
#include <stddef.h>
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/undo.h"

Data Structures

struct  wordcount_S
struct  suginfo_S
struct  suggest_T
struct  matchinf_S
struct  spelload_S
struct  syl_item_S
struct  sftword_T
struct  limitscore_T


#define RESCORE(word_score, sound_score)   ((3 * word_score + sound_score) / 4)
#define MAXSCORE(word_score, sound_score)   ((4 * word_score - sound_score) / 3)
#define WF_MIXCAP   0x20
#define SP_BANNED   -1
#define SP_RARE   0
#define SP_OK   1
#define SP_LOCAL   2
#define SP_BAD   3
#define WC_KEY_OFF   offsetof(wordcount_T, wc_word)
#define HI2WC(hi)   ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))
#define MAXWORDCOUNT   0xffff
#define SUG(ga, i)   (((suggest_T *)(ga).ga_data)[i])
#define WAS_BANNED(su, word)   (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))
#define SUG_CLEAN_COUNT(su)
#define SUG_MAX_COUNT(su)   (SUG_CLEAN_COUNT(su) + 50)
#define SCORE_SPLIT   149
#define SCORE_SPLIT_NO   249
#define SCORE_ICASE   52
#define SCORE_REGION   200
#define SCORE_RARE   180
#define SCORE_SWAP   75
#define SCORE_SWAP3   110
#define SCORE_REP   65
#define SCORE_SUBST   93
#define SCORE_SIMILAR   33
#define SCORE_SUBCOMP   33
#define SCORE_DEL   94
#define SCORE_DELDUP   66
#define SCORE_DELCOMP   28
#define SCORE_INS   96
#define SCORE_INSDUP   67
#define SCORE_INSCOMP   30
#define SCORE_NONWORD   103
#define SCORE_FILE   30
#define SCORE_MAXINIT   350
#define SCORE_COMMON1   30
#define SCORE_COMMON2   40
#define SCORE_COMMON3   50
#define SCORE_THRES2   10
#define SCORE_THRES3   100
#define SCORE_SFMAX1   200
#define SCORE_SFMAX2   300
#define SCORE_SFMAX3   400
#define SCORE_BIG   SCORE_INS * 3
#define SCORE_MAXMAX   999999
#define SCORE_LIMITMAX   350
#define SY_MAXLEN   30
#define DIFF_NONE   0
#define DIFF_YES   1
#define DIFF_INSERT   2
#define TSF_PREFIXOK   1
#define TSF_DIDSPLIT   2
#define TSF_DIDDEL   4
#define PFD_NOPREFIX   0xff
#define PFD_PREFIXTREE   0xfe
#define PFD_NOTSPECIAL   0xfd
#define FIND_FOLDWORD   0
#define FIND_KEEPWORD   1
#define FIND_PREFIX   2
#define FIND_COMPOUND   3
#define SPS_BEST   1
#define SPS_FAST   2
#define SPS_DOUBLE   4
#define FREE_SUG_WORD(sug)   xfree(sug->st_word)
#define PROF_STORE(state)
#define TRY_DEEPER(su, stack, depth, add)   (stack[depth].ts_score + (add) < su->su_maxscore)
#define HIKEY2SFT(p)   ((sftword_T *)(p - (dumsft.sft_word - (char_u *)&dumsft)))
#define HI2SFT(hi)   HIKEY2SFT((hi)->hi_key)
#define CNT(a, b)   cnt[(a) + (b) * (badlen + 1)]
#define DUMPFLAG_COUNT   2
#define DUMPFLAG_ICASE   4
#define DUMPFLAG_ALLCAP   16


typedef struct wordcount_S wordcount_T
typedef struct suginfo_S suginfo_T
typedef struct matchinf_S matchinf_T
typedef struct spelload_S spelload_T
typedef struct syl_item_S syl_item_T


size_t spell_check (win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docount)
size_t spell_move_to (win_T *wp, int dir, bool allwords, bool curline, hlf_T *attrp)
void spell_cat_line (char_u *buf, char_u *line, int maxlen)
char_uspell_enc (void)
slang_Tslang_alloc (char_u *lang) FUNC_ATTR_NONNULL_RET
void slang_free (slang_T *lp)
void slang_clear (slang_T *lp)
void slang_clear_sug (slang_T *lp)
void count_common_word (slang_T *lp, char_u *word, int len, int count)
bool byte_in_str (char_u *str, int n)
int init_syl_tab (slang_T *slang)
char * did_set_spelllang (win_T *wp)
int captype (char_u *word, char_u *end) FUNC_ATTR_NONNULL_ARG(1)
void spell_delete_wordlist (void)
void spell_free_all (void)
void spell_reload (void)
buf_Topen_spellbuf (void)
void close_spellbuf (buf_T *buf)
void clear_spell_chartab (spelltab_T *sp)
void init_spell_chartab (void)
bool spell_iswordp_nmw (const char_u *p, win_T *wp)
int spell_casefold (const win_T *wp, char_u *str, int len, char_u *buf, int buflen) FUNC_ATTR_NONNULL_ALL
int spell_check_sps (void)
void spell_suggest (int count)
void ex_spellrepall (exarg_T *eap)
void spell_suggest_list (garray_T *gap, char_u *word, int maxcount, bool need_cap, bool interactive)
void onecap_copy (char_u *word, char_u *wcopy, bool upper)
char * eval_soundfold (const char *const word) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
void spell_soundfold (slang_T *slang, char_u *inword, bool folded, char_u *res)
void ex_spellinfo (exarg_T *eap)
void ex_spelldump (exarg_T *eap)
void spell_dump_compl (char_u *pat, int ic, Direction *dir, int dumpflags_arg)
char_uspell_to_word_end (char_u *start, win_T *win)
int spell_word_start (int startcol)
void spell_expand_check_cap (colnr_T col)
int expand_spelling (linenr_T lnum, char_u *pat, char_u ***matchp)


slang_Tfirst_lang = NULL
char_uint_wordlist = NULL
spelltab_T spelltab
int did_set_spelltab
char * e_format = N_("E759: Format error in spell file")

Macro Definition Documentation


#define CNT (   a,
)    cnt[(a) + (b) * (badlen + 1)]


#define DIFF_INSERT   2


#define DIFF_NONE   0


#define DIFF_YES   1


#define DUMPFLAG_ALLCAP   16


#define DUMPFLAG_COUNT   2


#define DUMPFLAG_ICASE   4






#define FIND_COMPOUND   3


#define FIND_FOLDWORD   0




#define FIND_KEEPWORD   1


#define FIND_PREFIX   2


#define FREE_SUG_WORD (   sug)    xfree(sug->st_word)


#define HI2SFT (   hi)    HIKEY2SFT((hi)->hi_key)


#define HI2WC (   hi)    ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))


#define HIKEY2SFT (   p)    ((sftword_T *)(p - (dumsft.sft_word - (char_u *)&dumsft)))


#define MAXSCORE (   word_score,
)    ((4 * word_score - sound_score) / 3)


#define MAXWORDCOUNT   0xffff


#define PFD_NOPREFIX   0xff


#define PFD_NOTSPECIAL   0xfd


#define PFD_PREFIXTREE   0xfe


#define PROF_STORE (   state)


#define RESCORE (   word_score,
)    ((3 * word_score + sound_score) / 4)


#define SCORE_BIG   SCORE_INS * 3


#define SCORE_COMMON1   30


#define SCORE_COMMON2   40


#define SCORE_COMMON3   50


#define SCORE_DEL   94


#define SCORE_DELCOMP   28


#define SCORE_DELDUP   66




#define SCORE_FILE   30


#define SCORE_ICASE   52


#define SCORE_INS   96


#define SCORE_INSCOMP   30


#define SCORE_INSDUP   67


#define SCORE_LIMITMAX   350


#define SCORE_MAXINIT   350


#define SCORE_MAXMAX   999999


#define SCORE_NONWORD   103


#define SCORE_RARE   180


#define SCORE_REGION   200


#define SCORE_REP   65


#define SCORE_SFMAX1   200


#define SCORE_SFMAX2   300


#define SCORE_SFMAX3   400


#define SCORE_SIMILAR   33


#define SCORE_SPLIT   149


#define SCORE_SPLIT_NO   249


#define SCORE_SUBCOMP   33


#define SCORE_SUBST   93


#define SCORE_SWAP   75


#define SCORE_SWAP3   110


#define SCORE_THRES2   10


#define SCORE_THRES3   100


#define SP_BAD   3


#define SP_BANNED   -1


#define SP_LOCAL   2


#define SP_OK   1


#define SP_RARE   0


#define SPS_BEST   1


#define SPS_DOUBLE   4


#define SPS_FAST   2


#define SUG (   ga,
)    (((suggest_T *)(ga).ga_data)[i])


#define SUG_CLEAN_COUNT (   su)
((su)->su_maxcount < \
130 ? 150 : (su)->su_maxcount + 20)


#define SUG_MAX_COUNT (   su)    (SUG_CLEAN_COUNT(su) + 50)


#define SY_MAXLEN   30


#define TRY_DEEPER (   su,
)    (stack[depth].ts_score + (add) < su->su_maxscore)


#define TSF_DIDDEL   4


#define TSF_DIDSPLIT   2


#define TSF_PREFIXOK   1


#define WAS_BANNED (   su,
)    (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))


#define WC_KEY_OFF   offsetof(wordcount_T, wc_word)




#define WF_MIXCAP   0x20

Typedef Documentation

◆ matchinf_T

typedef struct matchinf_S matchinf_T

◆ spelload_T

typedef struct spelload_S spelload_T

◆ suginfo_T

typedef struct suginfo_S suginfo_T

◆ syl_item_T

typedef struct syl_item_S syl_item_T

◆ wordcount_T

typedef struct wordcount_S wordcount_T

Function Documentation

◆ byte_in_str()

bool byte_in_str ( char_u str,
int  n 

◆ captype()

int captype ( char_u word,
char_u end 

Return case type of word: w word 0 Word WF_ONECAP W WORD WF_ALLCAP WoRd wOrd WF_KEEPCAP

[in]endEnd of word or NULL for NUL delimited string
Case type of word

◆ clear_spell_chartab()

void clear_spell_chartab ( spelltab_T sp)

◆ close_spellbuf()

void close_spellbuf ( buf_T buf)

◆ count_common_word()

void count_common_word ( slang_T lp,
char_u word,
int  len,
int  count 

Add a word to the hashtable of common words. If it's already there then the counter is increased.

[in]wordadded to common words hashtable
[in]lenlength of word or -1 for NUL terminated
[in]count1 to count once, 10 to init

◆ did_set_spelllang()

char* did_set_spelllang ( win_T wp)

◆ eval_soundfold()

char* eval_soundfold ( const char *const  word)

Soundfold a string, for soundfold()

[in]wordWord to soundfold.
[allocated] soundfolded string or NULL in case of error. May return copy of the input string if soundfolding is not supported by any of the languages in &spellang.

◆ ex_spelldump()

void ex_spelldump ( exarg_T eap)

◆ ex_spellinfo()

void ex_spellinfo ( exarg_T eap)

◆ ex_spellrepall()

void ex_spellrepall ( exarg_T eap)

◆ expand_spelling()

int expand_spelling ( linenr_T  lnum,
char_u pat,
char_u ***  matchp 

◆ init_spell_chartab()

void init_spell_chartab ( void  )

◆ init_syl_tab()

int init_syl_tab ( slang_T slang)

◆ onecap_copy()

void onecap_copy ( char_u word,
char_u wcopy,
bool  upper 

Make a copy of "word", with the first letter upper or lower cased, to "wcopy[MAXWLEN]". "word" must not be empty. The result is NUL terminated.

[in]wordsource string to copy
[in,out]wcopycopied string, with case of first letter changed
[in]upperTrue to upper case, otherwise lower case

◆ open_spellbuf()

buf_T* open_spellbuf ( void  )

◆ slang_alloc()

slang_T* slang_alloc ( char_u lang)

◆ slang_clear()

void slang_clear ( slang_T lp)

◆ slang_clear_sug()

void slang_clear_sug ( slang_T lp)

◆ slang_free()

void slang_free ( slang_T lp)

◆ spell_casefold()

int spell_casefold ( const win_T wp,
char_u str,
int  len,
char_u buf,
int  buflen 

◆ spell_cat_line()

void spell_cat_line ( char_u buf,
char_u line,
int  maxlen 

◆ spell_check()

size_t spell_check ( win_T wp,
char_u ptr,
hlf_T attrp,
int *  capcol,
bool  docount 

Main spell-checking function. "ptr" points to a character that could be the start of a word. "*attrp" is set to the highlight index for a badly spelled word. For a non-word or when it's OK it remains unchanged. This must only be called when 'spelllang' is not empty.

"capcol" is used to check for a Capitalised word after the end of a sentence. If it's zero then perform the check. Return the column where to check next, or -1 when no sentence end was found. If it's NULL then don't worry.

wpcurrent window
capcolcolumn to check for Capital
docountcount good words
the length of the word in bytes, also when it's OK, so that the caller can skip over the word.

◆ spell_check_sps()

int spell_check_sps ( void  )

◆ spell_delete_wordlist()

void spell_delete_wordlist ( void  )

◆ spell_dump_compl()

void spell_dump_compl ( char_u pat,
int  ic,
Direction dir,
int  dumpflags_arg 

Go through all possible words and:

  1. When "pat" is NULL: dump a list of all words in the current buffer. "ic" and "dir" are not used.
  2. When "pat" is not NULL: add matching words to insert mode completion.
patleading part of the word
icignore case
dirdirection for adding matches

◆ spell_enc()

char_u* spell_enc ( void  )

◆ spell_expand_check_cap()

void spell_expand_check_cap ( colnr_T  col)

◆ spell_free_all()

void spell_free_all ( void  )

◆ spell_iswordp_nmw()

bool spell_iswordp_nmw ( const char_u p,
win_T wp 

◆ spell_move_to()

size_t spell_move_to ( win_T wp,
int  dir,
bool  allwords,
bool  curline,
hlf_T attrp 

Moves to the next spell error. "curline" is false for "[s", "]s", "[S" and "]S". "curline" is true to find word under/after cursor in the same line. For Insert mode completion "dir" is BACKWARD and "curline" is true: move to after badly spelled word before the cursor.

allwordstrue for "[s"/"]s", false for "[S"/"]S"
attrpreturn: attributes of bad word or NULL (only when "dir" is FORWARD)
0 if not found, length of the badly spelled word otherwise.

◆ spell_reload()

void spell_reload ( void  )

◆ spell_soundfold()

void spell_soundfold ( slang_T slang,
char_u inword,
bool  folded,
char_u res 

Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".

There are many ways to turn a word into a sound-a-like representation. The oldest is Soundex (1918!). A nice overview can be found in "Approximate swedish name matching - survey and test of different algorithms" by Klas Erikson.

We support two methods:

  1. SOFOFROM/SOFOTO do a simple character mapping.
  2. SAL items define a more advanced sound-folding (and much slower).
[in]inwordword to soundfold
[in]foldedwhether inword is already case-folded
[in,out]resdestination for soundfolded word

◆ spell_suggest()

void spell_suggest ( int  count)

◆ spell_suggest_list()

void spell_suggest_list ( garray_T gap,
char_u word,
int  maxcount,
bool  need_cap,
bool  interactive 

Find spell suggestions for "word". Return them in the growarray "*gap" as a list of allocated strings.

maxcountmaximum nr of suggestions
need_cap'spellcapcheck' matched

◆ spell_to_word_end()

char_u* spell_to_word_end ( char_u start,
win_T win 

◆ spell_word_start()

int spell_word_start ( int  startcol)

Variable Documentation

◆ did_set_spelltab

int did_set_spelltab

◆ e_format

char* e_format = N_("E759: Format error in spell file")

◆ first_lang

slang_T* first_lang = NULL

◆ int_wordlist

char_u* int_wordlist = NULL

◆ spelltab

spelltab_T spelltab