diff options
author | Bram Moolenaar <Bram@vim.org> | 2005-09-05 22:05:30 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2005-09-05 22:05:30 +0000 |
commit | 8b96d64cb57e63f92c335d217d685095ab7c59a7 (patch) | |
tree | 8b30feaa8e0d05b94f470397e50559738a10b6fb /src | |
parent | e344bead3ecc16a0982d157e8c19050f6dff4e0c (diff) | |
download | vim-git-8b96d64cb57e63f92c335d217d685095ab7c59a7.tar.gz |
updated for version 7.0141
Diffstat (limited to 'src')
-rw-r--r-- | src/mark.c | 3 | ||||
-rw-r--r-- | src/normal.c | 104 | ||||
-rw-r--r-- | src/spell.c | 279 |
3 files changed, 275 insertions, 111 deletions
diff --git a/src/mark.c b/src/mark.c index 1655e0357..d3db4a601 100644 --- a/src/mark.c +++ b/src/mark.c @@ -318,7 +318,8 @@ getmark(c, changefile) pos = curwin->w_cursor; listcmd_busy = TRUE; /* avoid that '' is changed */ - if (findpar(&oa, c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) + if (findpar(&oa.inclusive, + c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) { pos_copy = curwin->w_cursor; posp = &pos_copy; diff --git a/src/normal.c b/src/normal.c index e7cfad6e7..b184fd783 100644 --- a/src/normal.c +++ b/src/normal.c @@ -3921,23 +3921,45 @@ nv_page(cap) */ static void nv_gd(oap, nchar) - oparg_T *oap; - int nchar; + oparg_T *oap; + int nchar; { int len; + char_u *ptr; + + if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0 + || find_decl(ptr, len, nchar == 'd', 0) == FAIL) + clearopbeep(oap); +#ifdef FEAT_FOLDING + else if ((fdo_flags & FDO_SEARCH) && KeyTyped && oap->op_type == OP_NOP) + foldOpenCursor(); +#endif +} + +/* + * Search for variable declaration of "ptr[len]". When "locally" is TRUE in + * the current function ("gd"), otherwise in the current file ("gD"). + * Return FAIL when not found. + */ + int +find_decl(ptr, len, locally, searchflags) + char_u *ptr; + int len; + int locally; + int searchflags; /* flags passed to searchit() */ +{ char_u *pat; pos_T old_pos; + pos_T par_pos; + pos_T found_pos; int t; int save_p_ws; int save_p_scs; - char_u *ptr; + int retval = OK; + int incl; - if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0 - || (pat = alloc(len + 7)) == NULL) - { - clearopbeep(oap); - return; - } + if ((pat = alloc(len + 7)) == NULL) + return FAIL; /* Put "\V" before the pattern to avoid that the special meaning of "." * and "~" causes trouble. */ @@ -3954,42 +3976,70 @@ nv_gd(oap, nchar) * With "gd" Search back for the start of the current function, then go * back until a blank line. If this fails go to line 1. */ - if (nchar == 'D' || !findpar(oap, BACKWARD, 1L, '{', FALSE)) + if (!locally || !findpar(&incl, BACKWARD, 1L, '{', FALSE)) { setpcmark(); /* Set in findpar() otherwise */ curwin->w_cursor.lnum = 1; } else { + par_pos = curwin->w_cursor; while (curwin->w_cursor.lnum > 1 && *skipwhite(ml_get_curline()) != NUL) --curwin->w_cursor.lnum; } curwin->w_cursor.col = 0; /* Search forward for the identifier, ignore comment lines. */ - while ((t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD, pat, 1L, 0, - RE_LAST)) != FAIL + found_pos.lnum = 0; + for (;;) + { + t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD, + pat, 1L, searchflags, RE_LAST); + if (curwin->w_cursor.lnum >= old_pos.lnum) + t = FAIL; /* match after start is failure too */ + if (t == FAIL) + { + /* If we previously found a valid position, use it. */ + if (found_pos.lnum != 0) + { + curwin->w_cursor = found_pos; + t = OK; + } + break; + } #ifdef FEAT_COMMENTS - && get_leader_len(ml_get_curline(), NULL, FALSE) > 0 + if (get_leader_len(ml_get_curline(), NULL, FALSE) > 0) + { + /* Ignore this line, continue at start of next line. */ + ++curwin->w_cursor.lnum; + curwin->w_cursor.col = 0; + continue; + } #endif - && old_pos.lnum > curwin->w_cursor.lnum) - { - /* Ignore this line, continue at start of next line. */ - ++curwin->w_cursor.lnum; - curwin->w_cursor.col = 0; + if (!locally) /* global search: use first match found */ + break; + if (curwin->w_cursor.lnum >= par_pos.lnum) + { + /* If we previously found a valid position, use it. */ + if (found_pos.lnum != 0) + curwin->w_cursor = found_pos; + break; + } + + /* For finding a local variable and the match is before the "{" search + * to find a later match. For K&R style function declarations this + * skips the function header without types. */ + found_pos = curwin->w_cursor; } - if (t == FAIL || old_pos.lnum <= curwin->w_cursor.lnum) + + if (t == FAIL) { - clearopbeep(oap); + retval = FAIL; curwin->w_cursor = old_pos; } else { curwin->w_set_curswant = TRUE; -#ifdef FEAT_FOLDING - if ((fdo_flags & FDO_SEARCH) && KeyTyped && oap->op_type == OP_NOP) - foldOpenCursor(); -#endif /* "n" searches forward now */ reset_search_dir(); } @@ -3997,6 +4047,8 @@ nv_gd(oap, nchar) vim_free(pat); p_ws = save_p_ws; p_scs = save_p_scs; + + return retval; } /* @@ -6014,7 +6066,7 @@ nv_brackets(cap) * Imitate strange Vi behaviour: When using "]]" with an operator * we also stop at '}'. */ - if (!findpar(cap->oap, cap->arg, cap->count1, flag, + if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, flag, (cap->oap->op_type != OP_NOP && cap->arg == FORWARD && flag == '{'))) clearopbeep(cap->oap); @@ -6239,7 +6291,7 @@ nv_findpar(cap) cap->oap->inclusive = FALSE; cap->oap->use_reg_one = TRUE; curwin->w_set_curswant = TRUE; - if (!findpar(cap->oap, cap->arg, cap->count1, NUL, FALSE)) + if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, NUL, FALSE)) clearopbeep(cap->oap); else { diff --git a/src/spell.c b/src/spell.c index 2c21d94c8..c3c54b767 100644 --- a/src/spell.c +++ b/src/spell.c @@ -423,7 +423,9 @@ static slang_T *first_lang = NULL; */ typedef struct langp_S { - slang_T *lp_slang; /* info for this language (NULL for last one) */ + slang_T *lp_slang; /* info for this language */ + slang_T *lp_sallang; /* language used for sound folding or NULL */ + slang_T *lp_replang; /* language used for REP items or NULL */ int lp_region; /* bitmask for region or REGION_ALL */ } langp_T; @@ -476,6 +478,7 @@ typedef struct suginfo_S char_u su_badword[MAXWLEN]; /* bad word truncated at su_badlen */ char_u su_fbadword[MAXWLEN]; /* su_badword case-folded */ 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". */ @@ -487,6 +490,7 @@ typedef struct suggest_S 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]) @@ -740,7 +744,7 @@ static void suggest_try_soundalike __ARGS((suginfo_T *su)); static void make_case_word __ARGS((char_u *fword, char_u *cword, int flags)); static void set_map_str __ARGS((slang_T *lp, char_u *map)); static int similar_chars __ARGS((slang_T *slang, int c1, int c2)); -static void add_suggestion __ARGS((suginfo_T *su, garray_T *gap, char_u *goodword, int badlen, int score, int altscore, int had_bonus)); +static void add_suggestion __ARGS((suginfo_T *su, garray_T *gap, char_u *goodword, int badlen, int score, int altscore, int had_bonus, slang_T *slang)); static void add_banned __ARGS((suginfo_T *su, char_u *word)); static int was_banned __ARGS((suginfo_T *su, char_u *word)); static void free_banned __ARGS((suginfo_T *su)); @@ -1985,6 +1989,8 @@ spell_move_to(wp, dir, allwords, curline, attrp) * starting line again and accept the last match. */ lnum = wp->w_buffer->b_ml.ml_line_count; wrapped = TRUE; + if (!shortmess(SHM_SEARCH)) + give_warning((char_u *)_(top_bot_msg), TRUE); } capcol = -1; } @@ -2000,6 +2006,8 @@ spell_move_to(wp, dir, allwords, curline, attrp) * starting line again and accept the first match. */ lnum = 1; wrapped = TRUE; + if (!shortmess(SHM_SEARCH)) + give_warning((char_u *)_(bot_top_msg), TRUE); } /* If we are back at the starting line and there is no match then @@ -3540,7 +3548,7 @@ did_set_spelllang(buf) char_u region_cp[3]; int filename; int region_mask; - slang_T *lp; + slang_T *slang; int c; char_u lang[MAXWLEN + 1]; char_u spf_name[MAXPATHL]; @@ -3551,6 +3559,8 @@ did_set_spelllang(buf) char_u *use_region = NULL; int dont_use_region = FALSE; int nobreak = FALSE; + int i, j; + langp_T *lp, *lp2; ga_init2(&ga, sizeof(langp_T), 2); clear_midword(buf); @@ -3585,8 +3595,8 @@ did_set_spelllang(buf) dont_use_region = TRUE; /* Check if we loaded this language before. */ - for (lp = first_lang; lp != NULL; lp = lp->sl_next) - if (fullpathcmp(lang, lp->sl_fname, FALSE) == FPC_SAME) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) + if (fullpathcmp(lang, slang->sl_fname, FALSE) == FPC_SAME) break; } else @@ -3602,8 +3612,8 @@ did_set_spelllang(buf) dont_use_region = TRUE; /* Check if we loaded this language before. */ - for (lp = first_lang; lp != NULL; lp = lp->sl_next) - if (STRICMP(lang, lp->sl_name) == 0) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) + if (STRICMP(lang, slang->sl_name) == 0) break; } @@ -3617,7 +3627,7 @@ did_set_spelllang(buf) } /* If not found try loading the language now. */ - if (lp == NULL) + if (slang == NULL) { if (filename) (void)spell_load_file(lang, lang, NULL, FALSE); @@ -3628,20 +3638,20 @@ did_set_spelllang(buf) /* * Loop over the languages, there can be several files for "lang". */ - for (lp = first_lang; lp != NULL; lp = lp->sl_next) - if (filename ? fullpathcmp(lang, lp->sl_fname, FALSE) == FPC_SAME - : STRICMP(lang, lp->sl_name) == 0) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) + if (filename ? fullpathcmp(lang, slang->sl_fname, FALSE) == FPC_SAME + : STRICMP(lang, slang->sl_name) == 0) { region_mask = REGION_ALL; if (!filename && region != NULL) { /* find region in sl_regions */ - c = find_region(lp->sl_regions, region); + c = find_region(slang->sl_regions, region); if (c == REGION_ALL) { - if (lp->sl_add) + if (slang->sl_add) { - if (*lp->sl_regions != NUL) + if (*slang->sl_regions != NUL) /* This addition file is for other regions. */ region_mask = 0; } @@ -3663,11 +3673,11 @@ did_set_spelllang(buf) ga_clear(&ga); return e_outofmem; } - LANGP_ENTRY(ga, ga.ga_len)->lp_slang = lp; + LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang; LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask; ++ga.ga_len; - use_midword(lp, buf); - if (lp->sl_nobreak) + use_midword(slang, buf); + if (slang->sl_nobreak) nobreak = TRUE; } } @@ -3705,10 +3715,10 @@ did_set_spelllang(buf) } /* Check if it was loaded already. */ - for (lp = first_lang; lp != NULL; lp = lp->sl_next) - if (fullpathcmp(spf_name, lp->sl_fname, FALSE) == FPC_SAME) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) + if (fullpathcmp(spf_name, slang->sl_fname, FALSE) == FPC_SAME) break; - if (lp == NULL) + if (slang == NULL) { /* Not loaded, try loading it now. The language name includes the * region name, the region is ignored otherwise. for int_wordlist @@ -3722,33 +3732,35 @@ did_set_spelllang(buf) if (p != NULL) *p = NUL; /* truncate at ".encoding.add" */ } - lp = spell_load_file(spf_name, lang, NULL, TRUE); + slang = spell_load_file(spf_name, lang, NULL, TRUE); /* If one of the languages has NOBREAK we assume the addition * files also have this. */ - if (lp != NULL && nobreak) - lp->sl_nobreak = TRUE; + if (slang != NULL && nobreak) + slang->sl_nobreak = TRUE; } - if (lp != NULL && ga_grow(&ga, 1) == OK) + if (slang != NULL && ga_grow(&ga, 1) == OK) { region_mask = REGION_ALL; if (use_region != NULL && !dont_use_region) { /* find region in sl_regions */ - c = find_region(lp->sl_regions, use_region); + c = find_region(slang->sl_regions, use_region); if (c != REGION_ALL) region_mask = 1 << c; - else if (*lp->sl_regions != NUL) + else if (*slang->sl_regions != NUL) /* This spell file is for other regions. */ region_mask = 0; } if (region_mask != 0) { - LANGP_ENTRY(ga, ga.ga_len)->lp_slang = lp; + LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang; + LANGP_ENTRY(ga, ga.ga_len)->lp_sallang = NULL; + LANGP_ENTRY(ga, ga.ga_len)->lp_replang = NULL; LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask; ++ga.ga_len; - use_midword(lp, buf); + use_midword(slang, buf); } } } @@ -3757,6 +3769,50 @@ did_set_spelllang(buf) ga_clear(&buf->b_langp); buf->b_langp = ga; + /* For each language figure out what language to use for sound folding and + * REP items. If the language doesn't support it itself use another one + * with the same name. E.g. for "en-math" use "en". */ + for (i = 0; i < ga.ga_len; ++i) + { + lp = LANGP_ENTRY(ga, i); + + /* sound folding */ + if (lp->lp_slang->sl_sal.ga_len > 0) + /* language does sound folding itself */ + lp->lp_sallang = lp->lp_slang; + else + /* find first similar language that does sound folding */ + for (j = 0; j < ga.ga_len; ++j) + { + lp2 = LANGP_ENTRY(ga, j); + if (lp2->lp_slang->sl_sal.ga_len > 0 + && STRNCMP(lp->lp_slang->sl_name, + lp2->lp_slang->sl_name, 2) == 0) + { + lp->lp_sallang = lp2->lp_slang; + break; + } + } + + /* REP items */ + if (lp->lp_slang->sl_rep.ga_len > 0) + /* language has REP items itself */ + lp->lp_replang = lp->lp_slang; + else + /* find first similar language that does sound folding */ + for (j = 0; j < ga.ga_len; ++j) + { + lp2 = LANGP_ENTRY(ga, j); + if (lp2->lp_slang->sl_rep.ga_len > 0 + && STRNCMP(lp->lp_slang->sl_name, + lp2->lp_slang->sl_name, 2) == 0) + { + lp->lp_replang = lp2->lp_slang; + break; + } + } + } + return NULL; } @@ -3954,7 +4010,7 @@ badword_captype(word, end) void spell_free_all() { - slang_T *lp; + slang_T *slang; buf_T *buf; char_u fname[MAXPATHL]; @@ -3964,9 +4020,9 @@ spell_free_all() while (first_lang != NULL) { - lp = first_lang; - first_lang = lp->sl_next; - slang_free(lp); + slang = first_lang; + first_lang = slang->sl_next; + slang_free(slang); } if (int_wordlist != NULL) @@ -4028,17 +4084,17 @@ spell_reload_one(fname, added_word) char_u *fname; int added_word; /* invoked through "zg" */ { - slang_T *lp; + slang_T *slang; int didit = FALSE; - for (lp = first_lang; lp != NULL; lp = lp->sl_next) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (fullpathcmp(fname, lp->sl_fname, FALSE) == FPC_SAME) + if (fullpathcmp(fname, slang->sl_fname, FALSE) == FPC_SAME) { - slang_clear(lp); - if (spell_load_file(fname, NULL, lp, FALSE) == NULL) + slang_clear(slang); + if (spell_load_file(fname, NULL, slang, FALSE) == NULL) /* reloading failed, clear the language */ - slang_clear(lp); + slang_clear(slang); redraw_all_later(NOT_VALID); didit = TRUE; } @@ -8712,6 +8768,8 @@ spell_find_suggest(badptr, su, maxcount, banbadword, need_cap) static int expr_busy = FALSE; #endif int c; + int i; + langp_T *lp; /* * Set the info in "*su". @@ -8739,6 +8797,20 @@ spell_find_suggest(badptr, su, maxcount, banbadword, need_cap) if (need_cap) su->su_badflags |= WF_ONECAP; + /* Find the default language for sound folding. We simply use the first + * one in 'spelllang' that supports sound folding. That's good for when + * using multiple files for one language, it's not that bad when mixing + * languages (e.g., "pl,en"). */ + for (i = 0; i < curbuf->b_langp.ga_len; ++i) + { + lp = LANGP_ENTRY(curbuf->b_langp, i); + if (lp->lp_sallang != NULL) + { + su->su_sallang = lp->lp_sallang; + break; + } + } + /* 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 * for that. */ @@ -8747,7 +8819,7 @@ spell_find_suggest(badptr, su, maxcount, banbadword, need_cap) { make_case_word(su->su_badword, buf, WF_ONECAP); add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE, - 0, TRUE); + 0, TRUE, su->su_sallang); } /* Ban the bad word itself. It may appear in another region. */ @@ -8825,7 +8897,7 @@ spell_suggest_expr(su, expr) score = get_spellword(li->li_tv.vval.v_list, &p); if (score >= 0) add_suggestion(su, &su->su_ga, p, - su->su_badlen, score, 0, TRUE); + su->su_badlen, score, 0, TRUE, su->su_sallang); } list_unref(list); } @@ -8882,7 +8954,7 @@ spell_suggest_file(su, fname) } add_suggestion(su, &su->su_ga, p, su->su_badlen, - SCORE_FILE, 0, TRUE); + SCORE_FILE, 0, TRUE, su->su_sallang); } } @@ -9091,7 +9163,8 @@ suggest_try_special(su) su->su_fbadword[len] = NUL; make_case_word(su->su_fbadword, word, su->su_badflags); su->su_fbadword[len] = c; - add_suggestion(su, &su->su_ga, word, su->su_badlen, SCORE_DEL, 0, TRUE); + add_suggestion(su, &su->su_ga, word, su->su_badlen, SCORE_DEL, + 0, TRUE, su->su_sallang); } } @@ -9152,9 +9225,9 @@ suggest_try_change(su) p = su->su_badptr + su->su_badlen; (void)spell_casefold(p, STRLEN(p), fword + n, MAXWLEN - n); - for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi) { - lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); + lp = LANGP_ENTRY(curbuf->b_langp, lpi); slang = lp->lp_slang; /* If reloading a spell file fails it's still in the list but @@ -9340,8 +9413,9 @@ suggest_try_change(su) { preword[sp->ts_prewordlen] = NUL; add_suggestion(su, &su->su_ga, preword, - sp->ts_splitfidx - repextra, - sp->ts_score, 0, FALSE); + sp->ts_splitfidx - repextra, + sp->ts_score, 0, FALSE, + lp->lp_sallang); break; } } @@ -9466,7 +9540,8 @@ suggest_try_change(su) add_suggestion(su, &su->su_ga, preword, sp->ts_fidx - repextra, - sp->ts_score + newscore, 0, FALSE); + sp->ts_score + newscore, 0, FALSE, + lp->lp_sallang); } else if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends) #ifdef FEAT_MBYTE @@ -10161,19 +10236,22 @@ suggest_try_change(su) case STATE_REP_INI: /* Check if matching with REP items from the .aff file would - * work. Quickly skip if there are no REP items or the score - * is going to be too high anyway. */ - gap = &slang->sl_rep; - if (gap->ga_len == 0 - || sp->ts_score + SCORE_REP >= su->su_maxscore) + * work. Quickly skip if: + * - there are no REP items + * - the score is going to be too high anyway + * - already applied a REP item or swapped here */ + if (lp->lp_replang == NULL + || sp->ts_score + SCORE_REP >= su->su_maxscore + || sp->ts_fidx < sp->ts_fidxtry) { sp->ts_state = STATE_FINAL; break; } + gap = &lp->lp_replang->sl_rep; /* Use the first byte to quickly find the first entry that * may match. If the index is -1 there is none. */ - sp->ts_curi = slang->sl_rep_first[fword[sp->ts_fidx]]; + sp->ts_curi = lp->lp_replang->sl_rep_first[fword[sp->ts_fidx]]; if (sp->ts_curi < 0) { sp->ts_state = STATE_FINAL; @@ -10189,7 +10267,7 @@ suggest_try_change(su) * word is valid. */ p = fword + sp->ts_fidx; - gap = &slang->sl_rep; + gap = &lp->lp_replang->sl_rep; while (sp->ts_curi < gap->ga_len) { ftp = (fromto_T *)gap->ga_data + sp->ts_curi++; @@ -10223,7 +10301,7 @@ suggest_try_change(su) } } - if (sp->ts_curi >= gap->ga_len) + if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP) /* No (more) matches. */ sp->ts_state = STATE_FINAL; @@ -10231,7 +10309,8 @@ suggest_try_change(su) case STATE_REP_UNDO: /* Undo a REP replacement and continue with the next one. */ - ftp = (fromto_T *)slang->sl_rep.ga_data + sp->ts_curi - 1; + ftp = (fromto_T *)lp->lp_replang->sl_rep.ga_data + + sp->ts_curi - 1; fl = STRLEN(ftp->ft_from); tl = STRLEN(ftp->ft_to); p = fword + sp->ts_fidx; @@ -10490,9 +10569,9 @@ score_comp_sal(su) return; /* Use the sound-folding of the first language that supports it. */ - for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi) { - lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); + lp = LANGP_ENTRY(curbuf->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ @@ -10544,9 +10623,9 @@ score_combine(su) int lpi; /* Add the alternate score to su_ga. */ - for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi) { - lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); + lp = LANGP_ENTRY(curbuf->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ @@ -10669,6 +10748,7 @@ stp_sal_score(stp, su, slang, badsound) /* * Find suggestions by comparing the word in a sound-a-like form. + * Note: This doesn't support postponed prefixes. */ static void suggest_try_soundalike(su) @@ -10690,15 +10770,17 @@ suggest_try_soundalike(su) int sound_score; int local_score; int lpi; + slang_T *slang; /* Do this for all languages that support sound folding. */ - for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi) { - lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); - if (lp->lp_slang->sl_sal.ga_len > 0) + lp = LANGP_ENTRY(curbuf->b_langp, lpi); + slang = lp->lp_slang; + if (slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ - spell_soundfold(lp->lp_slang, su->su_fbadword, TRUE, salword); + spell_soundfold(slang, su->su_fbadword, TRUE, salword); /* * Go through the whole tree, soundfold each word and compare. @@ -10709,13 +10791,13 @@ suggest_try_soundalike(su) { if (round == 1) { - byts = lp->lp_slang->sl_fbyts; - idxs = lp->lp_slang->sl_fidxs; + byts = slang->sl_fbyts; + idxs = slang->sl_fidxs; } else { - byts = lp->lp_slang->sl_kbyts; - idxs = lp->lp_slang->sl_kidxs; + byts = slang->sl_kbyts; + idxs = slang->sl_kidxs; if (byts == NULL) /* no keep-case words */ continue; } @@ -10746,7 +10828,7 @@ suggest_try_soundalike(su) tword[depth] = NUL; /* Sound-fold. Only in keep-case tree need to * case-fold the word. */ - spell_soundfold(lp->lp_slang, tword, + spell_soundfold(slang, tword, round == 1, tsalword); /* Compute the edit distance between the @@ -10782,7 +10864,8 @@ suggest_try_soundalike(su) if (sps_flags & SPS_DOUBLE) add_suggestion(su, &su->su_sga, p, su->su_badlen, - sound_score, 0, FALSE); + sound_score, 0, FALSE, + lp->lp_sallang); else { /* Compute the score. */ @@ -10796,11 +10879,14 @@ suggest_try_soundalike(su) add_suggestion(su, &su->su_ga, p, su->su_badlen, RESCORE(score, sound_score), - sound_score, TRUE); + sound_score, TRUE, + lp->lp_sallang); else add_suggestion(su, &su->su_ga, p, su->su_badlen, - score + sound_score, 0, FALSE); + score + sound_score, + 0, FALSE, + lp->lp_sallang); } } } @@ -10985,7 +11071,7 @@ similar_chars(slang, c1, c2) * with spell_edit_score(). */ static void -add_suggestion(su, gap, goodword, badlen, score, altscore, had_bonus) +add_suggestion(su, gap, goodword, badlen, score, altscore, had_bonus, slang) suginfo_T *su; garray_T *gap; char_u *goodword; @@ -10993,6 +11079,7 @@ add_suggestion(su, gap, goodword, badlen, score, altscore, had_bonus) int score; int altscore; int had_bonus; /* value for st_had_bonus */ + slang_T *slang; /* language for sound folding */ { suggest_T *stp; int i; @@ -11048,6 +11135,8 @@ add_suggestion(su, gap, goodword, badlen, score, altscore, had_bonus) stp[i].st_altscore = altscore; stp[i].st_had_bonus = had_bonus; } + if (stp[i].st_slang == NULL) + stp[i].st_slang = slang; break; } @@ -11062,6 +11151,7 @@ add_suggestion(su, gap, goodword, badlen, score, altscore, had_bonus) stp->st_altscore = altscore; stp->st_had_bonus = had_bonus; stp->st_orglen = badlen; + stp->st_slang = slang; ++gap->ga_len; /* If we have too many suggestions now, sort the list and keep @@ -11146,30 +11236,51 @@ rescore_suggestions(su) langp_T *lp; suggest_T *stp; char_u sal_badword[MAXWLEN]; + char_u sal_badword2[MAXWLEN]; int i; int lpi; + slang_T *slang_first = NULL; + slang_T *slang; - for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi) { - lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); + lp = LANGP_ENTRY(curbuf->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ - spell_soundfold(lp->lp_slang, su->su_fbadword, TRUE, sal_badword); + slang_first = lp->lp_slang; + spell_soundfold(slang_first, su->su_fbadword, TRUE, sal_badword); + break; + } + } - for (i = 0; i < su->su_ga.ga_len; ++i) + if (slang_first != NULL) + { + for (i = 0; i < su->su_ga.ga_len; ++i) + { + /* Only rescore suggestions that have no sal score yet and do have + * a language. */ + stp = &SUG(su->su_ga, i); + if (!stp->st_had_bonus && stp->st_slang != NULL) { - stp = &SUG(su->su_ga, i); - if (!stp->st_had_bonus) + slang = stp->st_slang; + if (slang->sl_sal.ga_len > 0) { - stp->st_altscore = stp_sal_score(stp, su, - lp->lp_slang, sal_badword); + if (slang == slang_first) + stp->st_altscore = stp_sal_score(stp, su, + slang, sal_badword); + else + { + spell_soundfold(slang, su->su_fbadword, + TRUE, sal_badword2); + stp->st_altscore = stp_sal_score(stp, su, + slang, sal_badword2); + } if (stp->st_altscore == SCORE_MAXMAX) stp->st_altscore = SCORE_BIG; stp->st_score = RESCORE(stp->st_score, stp->st_altscore); } } - break; } } } @@ -11244,9 +11355,9 @@ eval_soundfold(word) if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) /* Use the sound-folding of the first language that supports it. */ - for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + for (lpi = 0; lpi < curbuf->b_langp.ga_len; ++lpi) { - lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); + lp = LANGP_ENTRY(curbuf->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the word */ |