diff options
Diffstat (limited to 'src/spell.c')
-rw-r--r-- | src/spell.c | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/src/spell.c b/src/spell.c index f8b8460339..015a7108b9 100644 --- a/src/spell.c +++ b/src/spell.c @@ -607,7 +607,7 @@ static int set_spell_charflags __ARGS((char_u *flags, char_u *upp)); static int set_spell_chartab __ARGS((char_u *fol, char_u *low, char_u *upp)); static void write_spell_chartab __ARGS((FILE *fd)); static int spell_casefold __ARGS((char_u *p, int len, char_u *buf, int buflen)); -static void spell_find_suggest __ARGS((char_u *badptr, suginfo_T *su, int maxcount, int banbadword)); +static void spell_find_suggest __ARGS((char_u *badptr, suginfo_T *su, int maxcount, int banbadword, int need_cap)); #ifdef FEAT_EVAL static void spell_suggest_expr __ARGS((suginfo_T *su, char_u *expr)); #endif @@ -5952,6 +5952,10 @@ spell_suggest() suginfo_T sug; suggest_T *stp; int mouse_used; + int need_cap; + regmatch_T regmatch; + int endcol; + char_u *line_copy = NULL; /* Find the start of the badly spelled word. */ if (spell_move_to(FORWARD, TRUE, TRUE) == FAIL @@ -5983,8 +5987,62 @@ spell_suggest() /* Get the word and its length. */ line = ml_get_curline(); + /* Figure out if the word should be capitalised. */ + need_cap = FALSE; + if (curbuf->b_cap_prog != NULL) + { + endcol = 0; + if (skipwhite(line) - line == curwin->w_cursor.col) + { + /* At start of line, check if previous line is empty or sentence + * ends there. */ + if (curwin->w_cursor.lnum == 1) + need_cap = TRUE; + else + { + line = ml_get(curwin->w_cursor.lnum - 1); + if (*skipwhite(line) == NUL) + need_cap = TRUE; + else + { + /* Append a space in place of the line break. */ + line_copy = concat_str(line, (char_u *)" "); + line = line_copy; + endcol = STRLEN(line); + } + } + } + else + endcol = curwin->w_cursor.col; + + if (endcol > 0) + { + /* Check if sentence ends before the bad word. */ + regmatch.regprog = curbuf->b_cap_prog; + regmatch.rm_ic = FALSE; + p = line + endcol; + for (;;) + { + mb_ptr_back(line, p); + if (p == line || SPELL_ISWORDP(p)) + break; + if (vim_regexec(®match, p, 0) + && regmatch.endp[0] == line + endcol) + { + need_cap = TRUE; + break; + } + } + } + + /* get the line again, we may have been using the previous one */ + line = ml_get_curline(); + vim_free(line_copy); + } + /* Get the list of suggestions */ - spell_find_suggest(line + curwin->w_cursor.col, &sug, (int)Rows - 2, TRUE); + spell_find_suggest(line + curwin->w_cursor.col, &sug, (int)Rows - 2, + TRUE, need_cap); if (sug.su_ga.ga_len == 0) MSG(_("Sorry, no suggestions")); @@ -6159,7 +6217,7 @@ spell_suggest_list(gap, word, maxcount) suggest_T *stp; char_u *wcopy; - spell_find_suggest(word, &sug, maxcount, FALSE); + spell_find_suggest(word, &sug, maxcount, FALSE, FALSE); /* Make room in "gap". */ ga_init2(gap, sizeof(char_u *), sug.su_ga.ga_len + 1); @@ -6192,11 +6250,12 @@ spell_suggest_list(gap, word, maxcount) * This is based on the mechanisms of Aspell, but completely reimplemented. */ static void -spell_find_suggest(badptr, su, maxcount, banbadword) +spell_find_suggest(badptr, su, maxcount, banbadword, need_cap) char_u *badptr; suginfo_T *su; int maxcount; int banbadword; /* don't include badword in suggestions */ + int need_cap; /* word should start with capital */ { int attr = 0; char_u buf[MAXPATHL]; @@ -6230,6 +6289,8 @@ spell_find_suggest(badptr, su, maxcount, banbadword) su->su_fbadword, MAXWLEN); /* get caps flags for bad word */ su->su_badflags = captype(su->su_badptr, su->su_badptr + su->su_badlen); + if (need_cap) + su->su_badflags |= WF_ONECAP; /* If the word is not capitalised and spell_check() doesn't consider the * word to be bad then it might need to be capitalised. Add a suggestion @@ -6237,7 +6298,7 @@ spell_find_suggest(badptr, su, maxcount, banbadword) #ifdef FEAT_MBYTE c = mb_ptr2char(su->su_badptr); #else - c = *p; + c = *su->su_badptr; #endif if (!SPELL_ISUPPER(c) && attr == 0) { @@ -7972,6 +8033,7 @@ suggest_try_soundalike(su) char_u *p; int score; + flags |= su->su_badflags; if (round == 1 && (flags & WF_CAPMASK) != 0) { /* Need to fix case according to |