diff options
author | Bram Moolenaar <Bram@vim.org> | 2005-08-29 22:25:38 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2005-08-29 22:25:38 +0000 |
commit | ac6e65f88da446bc764ff13a23d854fd72ffedcf (patch) | |
tree | 4c4cd8700dcb53ac3a236a056320e2caf062a23d /src | |
parent | 81f1ecbc4dc885a4757e5cc64002f4b22f397f18 (diff) | |
download | vim-git-ac6e65f88da446bc764ff13a23d854fd72ffedcf.tar.gz |
updated for version 7.0138v7.0138
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 3 | ||||
-rw-r--r-- | src/feature.h | 3 | ||||
-rw-r--r-- | src/fileio.c | 4 | ||||
-rw-r--r-- | src/if_xcmdsrv.c | 16 | ||||
-rw-r--r-- | src/mbyte.c | 28 | ||||
-rw-r--r-- | src/misc2.c | 5 | ||||
-rw-r--r-- | src/option.c | 22 | ||||
-rw-r--r-- | src/proto/mbyte.pro | 1 | ||||
-rw-r--r-- | src/spell.c | 306 | ||||
-rw-r--r-- | src/testdir/test58.in | 247 | ||||
-rw-r--r-- | src/testdir/test58.ok | 89 | ||||
-rw-r--r-- | src/testdir/test59.in | 225 | ||||
-rw-r--r-- | src/testdir/test59.ok | 122 | ||||
-rw-r--r-- | src/version.h | 4 |
14 files changed, 732 insertions, 343 deletions
diff --git a/src/eval.c b/src/eval.c index 01900713d..f14a69b38 100644 --- a/src/eval.c +++ b/src/eval.c @@ -10043,6 +10043,9 @@ f_has(argvars, rettv) #ifdef FEAT_CSCOPE "cscope", #endif +#ifdef CURSOR_SHAPE + "cursorshape", +#endif #ifdef DEBUG "debug", #endif diff --git a/src/feature.h b/src/feature.h index f007df69a..0ab57e93a 100644 --- a/src/feature.h +++ b/src/feature.h @@ -1081,7 +1081,8 @@ /* GUI and some consoles can change the shape of the cursor. The code is also * needed for the 'mouseshape' option. */ -#if defined(FEAT_GUI) || defined(MCH_CURSOR_SHAPE) || defined(FEAT_MOUSESHAPE) +#if defined(FEAT_GUI) || defined(MCH_CURSOR_SHAPE) || defined(FEAT_MOUSESHAPE) \ + || (defined(UNIX) && defined(FEAT_NORMAL)) # define CURSOR_SHAPE #endif diff --git a/src/fileio.c b/src/fileio.c index bb25ce7da..a34048cef 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -6865,6 +6865,10 @@ show_autocmd(ap, event) if (got_int) return; msg_outtrans(ac->cmd); +#ifdef FEAT_EVAL + if (p_verbose > 0) + last_set_msg(ac->scriptID); +#endif if (got_int) return; if (ac->next != NULL) diff --git a/src/if_xcmdsrv.c b/src/if_xcmdsrv.c index 4a091bd27..63faf0c18 100644 --- a/src/if_xcmdsrv.c +++ b/src/if_xcmdsrv.c @@ -460,10 +460,12 @@ serverSendToVim(dpy, name, cmd, result, server, asExpr, localLoop, silent) /* * Send the command to target interpreter by appending it to the * comm window in the communication window. + * Length must be computed exactly! */ - length = STRLEN(name) + STRLEN(cmd) + 14; #ifdef FEAT_MBYTE - length += STRLEN(p_enc); + length = STRLEN(name) + STRLEN(p_enc) + STRLEN(cmd) + 14; +#else + length = STRLEN(name) + STRLEN(cmd) + 10; #endif property = (char_u *)alloc((unsigned)length + 30); @@ -480,6 +482,7 @@ serverSendToVim(dpy, name, cmd, result, server, asExpr, localLoop, silent) serial++; sprintf((char *)property + length, "%c-r %x %d", 0, (int_u)commWindow, serial); + /* Add length of what "-r %x %d" resulted in, skipping the NUL. */ length += STRLEN(property + length + 1) + 1; res = AppendPropCarefully(dpy, w, commProperty, property, length + 1); @@ -787,9 +790,10 @@ serverSendReply(name, str) if (!WindowValid(dpy, win)) return -1; - length = STRLEN(str) + 11; #ifdef FEAT_MBYTE - length += STRLEN(p_enc); + length = STRLEN(p_enc) + STRLEN(str) + 14; +#else + length = STRLEN(str) + 10; #endif if ((property = (char_u *)alloc((unsigned)length + 30)) != NULL) { @@ -800,6 +804,7 @@ serverSendReply(name, str) sprintf((char *)property, "%cn%c-n %s%c-w %x", 0, 0, str, 0, (unsigned int)commWindow); #endif + /* Add length of what "%x" resulted in. */ length += STRLEN(property + length); res = AppendPropCarefully(dpy, win, commProperty, property, length + 1); vim_free(property); @@ -1268,11 +1273,12 @@ serverEventProc(dpy, eventPtr) ga_grow(&reply, 50 + STRLEN(p_enc)); sprintf(reply.ga_data, "%cr%c-E %s%c-s %s%c-r ", 0, 0, p_enc, 0, serial, 0); + reply.ga_len = 14 + STRLEN(serial); #else ga_grow(&reply, 50); sprintf(reply.ga_data, "%cr%c-s %s%c-r ", 0, 0, serial, 0); -#endif reply.ga_len = 10 + STRLEN(serial); +#endif } res = NULL; if (serverName != NULL && STRICMP(name, serverName) == 0) diff --git a/src/mbyte.c b/src/mbyte.c index 9f2df3ad4..d446a5b41 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -2706,17 +2706,37 @@ mb_prevptr(line, p) mb_charlen(str) char_u *str; { - int count; + char_u *p = str; + int count; - if (str == NULL) + if (p == NULL) return 0; - for (count = 0; *str != NUL; count++) - str += (*mb_ptr2len)(str); + for (count = 0; *p != NUL; count++) + p += (*mb_ptr2len)(p); return count; } +#if defined(FEAT_SYN_HL) || defined(PROTO) +/* + * Like mb_charlen() but for a string with specified length. + */ + int +mb_charlen_len(str, len) + char_u *str; + int len; +{ + char_u *p = str; + int count; + + for (count = 0; *p != NUL && p < str + len; count++) + p += (*mb_ptr2len)(p); + + return count; +} +#endif + /* * Try to un-escape a multi-byte character. * Used for the "to" and "from" part of a mapping. diff --git a/src/misc2.c b/src/misc2.c index 58fb434d4..305741554 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -1664,7 +1664,7 @@ vim_strbyte(string, c) /* * Search for last occurrence of "c" in "string". - * return NULL if not found. + * Return NULL if not found. * Does not handle multi-byte char for "c"! */ char_u * @@ -3289,6 +3289,8 @@ parse_shape_opt(what) return NULL; } +# if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \ + || defined(FEAT_MOUSESHAPE) || defined(PROTO) /* * Return the index into shape_table[] for the current mode. * When "mouse" is TRUE, consider indexes valid for the mouse pointer. @@ -3346,6 +3348,7 @@ get_shape_idx(mouse) #endif return SHAPE_IDX_N; } +#endif # if defined(FEAT_MOUSESHAPE) || defined(PROTO) static int old_mouse_shape = 0; diff --git a/src/option.c b/src/option.c index 9b0e6360e..98c0ad89a 100644 --- a/src/option.c +++ b/src/option.c @@ -3257,6 +3257,8 @@ set_init_2() #if !((defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI)) { + char_u *p; + /* * If 'background' wasn't set by the user, try guessing the value, * depending on the terminal name. Only need to check for terminals @@ -3264,16 +3266,24 @@ set_init_2() * "linux" Linux console * "screen.linux" Linux console with screen * "cygwin" Cygwin shell + * We also check the COLORFGBG environment variable, which is set by + * rxvt and derivatives. This variable contains either two or three + * values separated by semicolons; we want the last value in either + * case. If this value is 0-6 or 8, our background is dark. */ idx = findoption((char_u *)"bg"); if (!(options[idx].flags & P_WAS_SET) && (STRCMP(T_NAME, "linux") == 0 || STRCMP(T_NAME, "screen.linux") == 0 - || STRCMP(T_NAME, "cygwin") == 0)) + || STRCMP(T_NAME, "cygwin") == 0 + || ((p = mch_getenv("COLORFGBG")) != NULL + && (p = vim_strrchr(p, ';')) != NULL + && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8') + && p[2] == NUL))) { set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE); - /* don't mark it as set, when starting the GUI it may be changed - * again */ + /* don't mark it as set, when starting the GUI it may be + * changed again */ options[idx].flags &= ~P_WAS_SET; } } @@ -9777,15 +9787,15 @@ compatible_set() static void fill_breakat_flags() { - char_u *c; + char_u *p; int i; for (i = 0; i < 256; i++) breakat_flags[i] = FALSE; if (p_breakat != NULL) - for (c = p_breakat; *c; c++) - breakat_flags[*c] = TRUE; + for (p = p_breakat; *p; p++) + breakat_flags[*p] = TRUE; } # if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro index 8af1cc227..9bff4d3db 100644 --- a/src/proto/mbyte.pro +++ b/src/proto/mbyte.pro @@ -55,6 +55,7 @@ void mb_adjust_cursor __ARGS((void)); void mb_adjustpos __ARGS((pos_T *lp)); char_u *mb_prevptr __ARGS((char_u *line, char_u *p)); int mb_charlen __ARGS((char_u *str)); +int mb_charlen_len __ARGS((char_u *str, int len)); char_u *mb_unescape __ARGS((char_u **pp)); int mb_lefthalve __ARGS((int row, int col)); int mb_fix_col __ARGS((int col, int row)); diff --git a/src/spell.c b/src/spell.c index 26d80500f..2b04bf8b3 100644 --- a/src/spell.c +++ b/src/spell.c @@ -214,9 +214,9 @@ * WF_REGION <region> follows * WF_AFX <affixID> follows * - * <flags2> 1 byte Only used when there are postponed prefixes. - * Bitmask of: + * <flags2> 1 byte Bitmask of: * WF_HAS_AFF >> 8 word includes affix + * WF_NEEDCOMP >> 8 word only valid in compound * * <pflags> 1 byte bitmask of: * WFP_RARE rare prefix @@ -273,6 +273,7 @@ typedef long idx_T; /* for <flags2>, shifted up one byte to be used in wn_flags */ #define WF_HAS_AFF 0x0100 /* word includes affix */ +#define WF_NEEDCOMP 0x0200 /* word only valid in compound */ #define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP) @@ -754,7 +755,7 @@ static void spell_soundfold_wsal __ARGS((slang_T *slang, char_u *inword, char_u static int soundalike_score __ARGS((char_u *goodsound, char_u *badsound)); static int spell_edit_score __ARGS((char_u *badword, char_u *goodword)); static void dump_word __ARGS((char_u *word, int round, int flags, linenr_T lnum)); -static linenr_T apply_prefixes __ARGS((slang_T *slang, char_u *word, int round, int flags, linenr_T startlnum)); +static linenr_T dump_prefixes __ARGS((slang_T *slang, char_u *word, int round, int flags, linenr_T startlnum)); /* * Use our own character-case definitions, because the current locale may @@ -834,6 +835,7 @@ spell_check(wp, ptr, attrp, capcol) int nrlen = 0; /* found a number first */ int c; int wrongcaplen = 0; + int lpi; /* A word never starts at a space or a control character. Return quickly * then, skipping over the character. */ @@ -907,9 +909,15 @@ spell_check(wp, ptr, attrp, capcol) * We check them all, because a matching word may be longer than an * already found matching word. */ - for (mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, 0); - mi.mi_lp->lp_slang != NULL; ++mi.mi_lp) + for (lpi = 0; lpi < wp->w_buffer->b_langp.ga_len; ++lpi) { + mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, lpi); + + /* If reloading fails the language is still in the list but everything + * has been cleared. */ + if (mi.mi_lp->lp_slang->sl_fidxs == NULL) + continue; + /* Check for a matching word in case-folded words. */ find_word(&mi, FIND_FOLDWORD); @@ -973,23 +981,26 @@ spell_check(wp, ptr, attrp, capcol) /* First language in 'spelllang' is NOBREAK. Find first position * at which any word would be valid. */ mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, 0); - p = mi.mi_word; - fp = mi.mi_fword; - for (;;) + if (mi.mi_lp->lp_slang->sl_fidxs != NULL) { - mb_ptr_adv(p); - mb_ptr_adv(fp); - if (p >= mi.mi_end) - break; - mi.mi_compoff = fp - mi.mi_fword; - find_word(&mi, FIND_COMPOUND); - if (mi.mi_result != SP_BAD) + p = mi.mi_word; + fp = mi.mi_fword; + for (;;) { - mi.mi_end = p; - break; + mb_ptr_adv(p); + mb_ptr_adv(fp); + if (p >= mi.mi_end) + break; + mi.mi_compoff = fp - mi.mi_fword; + find_word(&mi, FIND_COMPOUND); + if (mi.mi_result != SP_BAD) + { + mi.mi_end = p; + break; + } } + mi.mi_result = save_result; } - mi.mi_result = save_result; } if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED) @@ -1284,6 +1295,15 @@ find_word(mip, mode) if (((unsigned)flags >> 24) == 0 || wlen - mip->mi_compoff < slang->sl_compminlen) continue; +#ifdef FEAT_MBYTE + /* For multi-byte chars check character length against + * COMPOUNDMIN. */ + if (has_mbyte + && slang->sl_compminlen < MAXWLEN + && mb_charlen_len(mip->mi_word + mip->mi_compoff, + wlen - mip->mi_compoff) < slang->sl_compminlen) + continue; +#endif /* Limit the number of compound words to COMPOUNDMAX if no * maximum for syllables is specified. */ @@ -1358,6 +1378,10 @@ find_word(mip, mode) } } + /* Check NEEDCOMPOUND: can't use word without compounding. */ + else if (flags & WF_NEEDCOMP) + continue; + nobreak_result = SP_OK; if (!word_ends) @@ -1762,7 +1786,8 @@ no_spell_checking(wp) /* * Move to next spell error. - * "curline" is TRUE for "z?": find word under/after cursor in the same line. + * "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. * Return 0 if not found, length of the badly spelled word otherwise. @@ -1771,7 +1796,7 @@ no_spell_checking(wp) spell_move_to(wp, dir, allwords, curline, attrp) win_T *wp; int dir; /* FORWARD or BACKWARD */ - int allwords; /* TRUE for "[s" and "]s" */ + int allwords; /* TRUE for "[s"/"]s", FALSE for "[S"/"]S" */ int curline; int *attrp; /* return: attributes of bad word or NULL */ { @@ -1790,6 +1815,8 @@ spell_move_to(wp, dir, allwords, curline, attrp) int buflen = 0; int skip = 0; int capcol = -1; + int found_one = FALSE; + int wrapped = FALSE; if (no_spell_checking(wp)) return 0; @@ -1840,9 +1867,11 @@ spell_move_to(wp, dir, allwords, curline, attrp) endp = buf + len; while (p < endp) { - /* When searching backward don't search after the cursor. */ + /* When searching backward don't search after the cursor. Unless + * we wrapped around the end of the buffer. */ if (dir == BACKWARD && lnum == wp->w_cursor.lnum + && !wrapped && (colnr_T)(p - buf) >= wp->w_cursor.col) break; @@ -1855,14 +1884,17 @@ spell_move_to(wp, dir, allwords, curline, attrp) /* We found a bad word. Check the attribute. */ if (allwords || attr == highlight_attr[HLF_SPB]) { + found_one = TRUE; + /* When searching forward only accept a bad word after * the cursor. */ if (dir == BACKWARD - || lnum > wp->w_cursor.lnum + || lnum != wp->w_cursor.lnum || (lnum == wp->w_cursor.lnum - && (colnr_T)(curline ? p - buf + len + && (wrapped + || (colnr_T)(curline ? p - buf + len : p - buf) - > wp->w_cursor.col)) + > wp->w_cursor.col))) { if (has_syntax) { @@ -1906,7 +1938,7 @@ spell_move_to(wp, dir, allwords, curline, attrp) if (dir == BACKWARD && found_pos.lnum != 0) { - /* Use the last match in the line. */ + /* Use the last match in the line (before the cursor). */ wp->w_cursor = found_pos; vim_free(buf); return found_len; @@ -1918,16 +1950,42 @@ spell_move_to(wp, dir, allwords, curline, attrp) /* Advance to next line. */ if (dir == BACKWARD) { - if (lnum == 1) + /* If we are back at the starting line and searched it again there + * is no match, give up. */ + if (lnum == wp->w_cursor.lnum && wrapped) break; - --lnum; + + if (lnum > 1) + --lnum; + else if (!p_ws) + break; /* at first line and 'nowrapscan' */ + else + { + /* Wrap around to the end of the buffer. May search the + * starting line again and accept the last match. */ + lnum = wp->w_buffer->b_ml.ml_line_count; + wrapped = TRUE; + } capcol = -1; } else { - if (lnum == wp->w_buffer->b_ml.ml_line_count) + if (lnum < wp->w_buffer->b_ml.ml_line_count) + ++lnum; + else if (!p_ws) + break; /* at first line and 'nowrapscan' */ + else + { + /* Wrap around to the start of the buffer. May search the + * starting line again and accept the first match. */ + lnum = 1; + wrapped = TRUE; + } + + /* If we are back at the starting line and there is no match then + * give up. */ + if (lnum == wp->w_cursor.lnum && !found_one) break; - ++lnum; /* Skip the characters at the start of the next line that were * included in a match crossing line boundaries. */ @@ -2450,10 +2508,8 @@ endFAIL: /* truncating the name signals the error to spell_load_lang() */ *lang = NUL; if (lp != NULL && old_lp == NULL) - { slang_free(lp); - lp = NULL; - } + lp = NULL; endOK: if (fd != NULL) @@ -2885,7 +2941,7 @@ read_compound(fd, slang, len) --todo; c = getc(fd); /* <compminlen> */ if (c < 1) - c = 3; + c = MAXWLEN; slang->sl_compminlen = c; --todo; @@ -2972,7 +3028,7 @@ read_compound(fd, slang, len) } else /* normal char, "[abc]" and '*' are copied as-is */ { - if (c == '+') + if (c == '+' || c == '~') *pp++ = '\\'; /* "a+" becomes "a\+" */ #ifdef FEAT_MBYTE if (enc_utf8) @@ -3594,10 +3650,11 @@ did_set_spelllang(buf) /* If it was already found above then skip it. */ for (c = 0; c < ga.ga_len; ++c) - if (fullpathcmp(spf_name, - LANGP_ENTRY(ga, c)->lp_slang->sl_fname, - FALSE) == FPC_SAME) + { + p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname; + if (p != NULL && fullpathcmp(spf_name, p, FALSE) == FPC_SAME) break; + } if (c < ga.ga_len) continue; } @@ -3646,15 +3703,6 @@ did_set_spelllang(buf) } } - /* Add a NULL entry to mark the end of the list. */ - if (ga_grow(&ga, 1) == FAIL) - { - ga_clear(&ga); - return e_outofmem; - } - LANGP_ENTRY(ga, ga.ga_len)->lp_slang = NULL; - ++ga.ga_len; - /* Everything is fine, store the new b_langp value. */ ga_clear(&buf->b_langp); buf->b_langp = ga; @@ -3934,13 +3982,17 @@ spell_reload_one(fname, added_word) int didit = FALSE; for (lp = first_lang; lp != NULL; lp = lp->sl_next) + { if (fullpathcmp(fname, lp->sl_fname, FALSE) == FPC_SAME) { slang_clear(lp); - (void)spell_load_file(fname, NULL, lp, FALSE); + if (spell_load_file(fname, NULL, lp, FALSE) == NULL) + /* reloading failed, clear the language */ + slang_clear(lp); redraw_all_later(NOT_VALID); didit = TRUE; } + } /* When "zg" was used and the file wasn't loaded yet, should redo * 'spelllang' to get it loaded. */ @@ -3967,6 +4019,7 @@ typedef struct afffile_S unsigned af_kep; /* KEP ID for keep-case word */ unsigned af_bad; /* BAD ID for banned word */ unsigned af_needaffix; /* NEEDAFFIX ID */ + unsigned af_needcomp; /* NEEDCOMPOUND ID */ int af_pfxpostpone; /* postpone prefixes without chop string */ hashtab_T af_pref; /* hashtable for prefixes, affheader_T */ hashtab_T af_suff; /* hashtable for suffixes, affheader_T */ @@ -4129,13 +4182,14 @@ typedef struct spellinfo_S garray_T si_prefcond; /* table with conditions for postponed * prefixes, each stored as a string */ int si_newprefID; /* current value for ah_newID */ - int si_compID; /* current value for compound ID */ + int si_newcompID; /* current value for compound ID */ } spellinfo_T; static afffile_T *spell_read_aff __ARGS((spellinfo_T *spin, char_u *fname)); static unsigned affitem2flag __ARGS((int flagtype, char_u *item, char_u *fname, int lnum)); static unsigned get_affitem __ARGS((int flagtype, char_u **pp)); static void process_compflags __ARGS((spellinfo_T *spin, afffile_T *aff, char_u *compflags)); +static void check_renumber __ARGS((spellinfo_T *spin)); static int flag_in_afflist __ARGS((int flagtype, char_u *afflist, unsigned flag)); static void aff_check_number __ARGS((int spinval, int affval, char *name)); static void aff_check_string __ARGS((char_u *spinval, char_u *affval, char *name)); @@ -4161,7 +4215,7 @@ static void free_wordnode __ARGS((spellinfo_T *spin, wordnode_T *n)); static void wordtree_compress __ARGS((spellinfo_T *spin, wordnode_T *root)); static int node_compress __ARGS((spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, int *tot)); static int node_equal __ARGS((wordnode_T *n1, wordnode_T *n2)); -static void write_vim_spell __ARGS((spellinfo_T *spin, char_u *fname)); +static int write_vim_spell __ARGS((spellinfo_T *spin, char_u *fname)); static void clear_node __ARGS((wordnode_T *node)); static int put_node __ARGS((FILE *fd, wordnode_T *node, int index, int regionmask, int prefixtree)); static void mkspell __ARGS((int fcount, char_u **fnames, int ascii, int overwrite, int added_word)); @@ -4445,7 +4499,9 @@ spell_read_aff(spin, fname) smsg((char_u *)_("Invalid value for FLAG in %s line %d: %s"), fname, lnum, items[1]); if (aff->af_rar != 0 || aff->af_kep != 0 || aff->af_bad != 0 - || aff->af_needaffix != 0 || compflags != NULL + || aff->af_needaffix != 0 + || aff->af_needcomp != 0 + || compflags != NULL || aff->af_suff.ht_used > 0 || aff->af_pref.ht_used > 0) smsg((char_u *)_("FLAG after using flags in %s line %d: %s"), @@ -4496,6 +4552,12 @@ spell_read_aff(spin, fname) aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } + else if (STRCMP(items[0], "NEEDCOMPOUND") == 0 && itemcnt == 2 + && aff->af_needcomp == 0) + { + aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1], + fname, lnum); + } else if (STRCMP(items[0], "COMPOUNDFLAG") == 0 && itemcnt == 2 && compflags == NULL) { @@ -4608,8 +4670,9 @@ spell_read_aff(spin, fname) if (cur_aff->ah_flag == aff->af_bad || cur_aff->ah_flag == aff->af_rar || cur_aff->ah_flag == aff->af_kep - || cur_aff->ah_flag == aff->af_needaffix) - smsg((char_u *)_("Affix also used for BAD/RAR/KEP/NEEDAFFIX in %s line %d: %s"), + || cur_aff->ah_flag == aff->af_needaffix + || cur_aff->ah_flag == aff->af_needcomp) + smsg((char_u *)_("Affix also used for BAD/RAR/KEP/NEEDAFFIX/NEEDCOMPOUND in %s line %d: %s"), fname, lnum, items[1]); STRCPY(cur_aff->ah_key, items[1]); hash_add(tp, cur_aff->ah_key); @@ -4643,6 +4706,7 @@ spell_read_aff(spin, fname) { /* Use a new number in the .spl file later, to be able * to handle multiple .aff files. */ + check_renumber(spin); cur_aff->ah_newID = ++spin->si_newprefID; /* We only really use ah_newID if the prefix is @@ -5011,11 +5075,11 @@ spell_read_aff(spin, fname) process_compflags(spin, aff, compflags); /* Check that we didn't use too many renumbered flags. */ - if (spin->si_compID < spin->si_newprefID) + if (spin->si_newcompID < spin->si_newprefID) { - if (spin->si_compID == 255) + if (spin->si_newcompID == 127 || spin->si_newcompID == 255) MSG(_("Too many postponed prefixes")); - else if (spin->si_newprefID == 0) + else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) MSG(_("Too many compound flags")); else MSG(_("Too many posponed prefixes and/or compound flags")); @@ -5199,8 +5263,9 @@ process_compflags(spin, aff, compflags) * regexp (also inside []). */ do { - id = spin->si_compID--; - } while (vim_strchr((char_u *)"/*+[]\\-^", id) != NULL); + check_renumber(spin); + id = spin->si_newcompID--; + } while (vim_strchr((char_u *)"/+*[]\\-^", id) != NULL); ci->ci_newID = id; hash_add(&aff->af_comp, ci->ci_key); } @@ -5215,6 +5280,23 @@ process_compflags(spin, aff, compflags) } /* + * Check that the new IDs for postponed affixes and compounding don't overrun + * each other. We have almost 255 available, but start at 0-127 to avoid + * using two bytes for utf-8. When the 0-127 range is used up go to 128-255. + * When that is used up an error message is given. + */ + static void +check_renumber(spin) + spellinfo_T *spin; +{ + if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128) + { + spin->si_newprefID = 127; + spin->si_newcompID = 255; + } +} + +/* * Return TRUE if flag "flag" appears in affix list "afflist". */ static int @@ -5579,6 +5661,9 @@ spell_read_dic(spin, fname, affile) if (affile->af_needaffix != 0 && flag_in_afflist( affile->af_flagtype, afflist, affile->af_needaffix)) need_affix = TRUE; + if (affile->af_needcomp != 0 && flag_in_afflist( + affile->af_flagtype, afflist, affile->af_needcomp)) + flags |= WF_NEEDCOMP; if (affile->af_pfxpostpone) /* Need to store the list of prefix IDs with the word. */ @@ -6703,8 +6788,9 @@ rep_compare(s1, s2) /* * Write the Vim .spl file "fname". + * Return FAIL or OK; */ - static void + static int write_vim_spell(spin, fname) spellinfo_T *spin; char_u *fname; @@ -6720,18 +6806,22 @@ write_vim_spell(spin, fname) fromto_T *ftp; char_u *p; int rr; + int retval = OK; fd = mch_fopen((char *)fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), fname); - return; + return FAIL; } /* <HEADER>: <fileID> <versionnr> */ /* <fileID> */ if (fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd) != 1) + { EMSG(_(e_write)); + retval = FAIL; + } putc(VIMSPELLVERSION, fd); /* <versionnr> */ /* @@ -6995,7 +7085,14 @@ write_vim_spell(spin, fname) (void)put_node(fd, tree, 0, regionmask, round == 3); } - fclose(fd); + /* Write another byte to check for errors. */ + if (putc(0, fd) == EOF) + retval = FAIL; + + if (fclose(fd) == EOF) + retval = FAIL; + + return retval; } /* @@ -7221,7 +7318,7 @@ mkspell(fcount, fnames, ascii, overwrite, added_word) ga_init2(&spin.si_sal, (int)sizeof(fromto_T), 20); ga_init2(&spin.si_map, (int)sizeof(char_u), 100); ga_init2(&spin.si_prefcond, (int)sizeof(char_u *), 50); - spin.si_compID = 255; /* start compound ID at maximum, going down */ + spin.si_newcompID = 127; /* start compound ID at first maximum */ /* default: fnames[0] is output file, following are input files */ innames = &fnames[1]; @@ -7407,7 +7504,7 @@ mkspell(fcount, fnames, ascii, overwrite, added_word) verbose_leave(); } - write_vim_spell(&spin, wfname); + error = write_vim_spell(&spin, wfname) == FAIL; if (spin.si_verbose || p_verbose > 2) { @@ -7422,7 +7519,8 @@ mkspell(fcount, fnames, ascii, overwrite, added_word) } /* If the file is loaded need to reload it. */ - spell_reload_one(wfname, added_word); + if (!error) + spell_reload_one(wfname, added_word); } /* Free the allocated memory. */ @@ -7602,7 +7700,7 @@ init_spellfile() { char_u buf[MAXPATHL]; int l; - slang_T *sl; + char_u *fname; char_u *rtp; char_u *lend; @@ -7624,12 +7722,14 @@ init_spellfile() { /* Use the first language name from 'spelllang' and the * encoding used in the first loaded .spl file. */ - sl = LANGP_ENTRY(curbuf->b_langp, 0)->lp_slang; + fname = LANGP_ENTRY(curbuf->b_langp, 0)->lp_slang->sl_fname; + if (fname == NULL) + break; l = STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell/%.*s.%s.add", (int)(lend - curbuf->b_p_spl), curbuf->b_p_spl, - strstr((char *)gettail(sl->sl_fname), ".ascii.") != NULL + strstr((char *)gettail(fname), ".ascii.") != NULL ? (char_u *)"ascii" : spell_enc()); set_option_value((char_u *)"spellfile", 0L, buf, OPT_LOCAL); break; @@ -8976,6 +9076,7 @@ suggest_try_change(su) int repextra = 0; /* extra bytes in fword[] from REP item */ slang_T *slang; int fword_ends; + int lpi; /* We make a copy of the case-folded bad word, so that we can modify it * to find matches (esp. REP items). Append some more text, changing @@ -8985,11 +9086,16 @@ suggest_try_change(su) p = su->su_badptr + su->su_badlen; (void)spell_casefold(p, STRLEN(p), fword + n, MAXWLEN - n); - for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0); - lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) { + lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); slang = lp->lp_slang; + /* If reloading a spell file fails it's still in the list but + * everything has been cleared. */ + if (slang->sl_fbyts == NULL) + continue; + /* * Go through the whole case-fold tree, try changes at each node. * "tword[]" contains the word collected from nodes in the tree. @@ -9146,6 +9252,11 @@ suggest_try_change(su) } } + /* Check NEEDCOMPOUND: can't use word without compounding. */ + if (sp->ts_complen == sp->ts_compsplit && fword_ends + && (flags & WF_NEEDCOMP)) + break; + if (sp->ts_complen > sp->ts_compsplit) { if (slang->sl_nobreak) @@ -9178,6 +9289,16 @@ suggest_try_change(su) || sp->ts_twordlen - sp->ts_splitoff < slang->sl_compminlen) break; +#ifdef FEAT_MBYTE + /* For multi-byte chars check character length against + * COMPOUNDMIN. */ + if (has_mbyte + && slang->sl_compminlen < MAXWLEN + && mb_charlen(tword + sp->ts_splitoff) + < slang->sl_compminlen) + break; +#endif + compflags[sp->ts_complen] = ((unsigned)flags >> 24); compflags[sp->ts_complen + 1] = NUL; vim_strncpy(preword + sp->ts_prewordlen, @@ -9307,6 +9428,12 @@ suggest_try_change(su) && ((unsigned)flags >> 24) != 0 && sp->ts_twordlen - sp->ts_splitoff >= slang->sl_compminlen +#ifdef FEAT_MBYTE + && (!has_mbyte + || slang->sl_compminlen == MAXWLEN + || mb_charlen(tword + sp->ts_splitoff) + >= slang->sl_compminlen) +#endif && (slang->sl_compsylmax < MAXWLEN || sp->ts_complen + 1 - sp->ts_compsplit < slang->sl_compmax) @@ -10282,13 +10409,15 @@ score_comp_sal(su) suggest_T *stp; suggest_T *sstp; int score; + int lpi; if (ga_grow(&su->su_sga, su->su_ga.ga_len) == FAIL) return; /* Use the sound-folding of the first language that supports it. */ - for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0); - lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + { + lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ @@ -10317,6 +10446,7 @@ score_comp_sal(su) } break; } + } } /* @@ -10336,11 +10466,12 @@ score_combine(su) char_u *p; char_u badsound[MAXWLEN]; int round; + int lpi; /* Add the alternate score to su_ga. */ - for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0); - lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) { + lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ @@ -10483,11 +10614,12 @@ suggest_try_soundalike(su) int flags; int sound_score; int local_score; + int lpi; /* Do this for all languages that support sound folding. */ - for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0); - lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) { + lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ @@ -10940,10 +11072,11 @@ rescore_suggestions(su) suggest_T *stp; char_u sal_badword[MAXWLEN]; int i; + int lpi; - for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0); - lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) { + lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the bad word */ @@ -11032,17 +11165,20 @@ eval_soundfold(word) { langp_T *lp; char_u sound[MAXWLEN]; + int lpi; if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) /* Use the sound-folding of the first language that supports it. */ - for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0); - lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < curwin->w_buffer->b_langp.ga_len; ++lpi) + { + lp = LANGP_ENTRY(curwin->w_buffer->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { /* soundfold the word */ spell_soundfold(lp->lp_slang, word, FALSE, sound); return vim_strsave(sound); } + } /* No language with sound folding, return word as-is. */ return vim_strsave(word); @@ -12119,6 +12255,7 @@ ex_spelldump(eap) char_u *region_names = NULL; /* region names being used */ int do_region = TRUE; /* dump region names and numbers */ char_u *p; + int lpi; if (no_spell_checking(curwin)) return; @@ -12130,8 +12267,9 @@ ex_spelldump(eap) /* Find out if we can support regions: All languages must support the same * regions or none at all. */ - for (lp = LANGP_ENTRY(buf->b_langp, 0); lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < buf->b_langp.ga_len; ++lpi) { + lp = LANGP_ENTRY(buf->b_langp, lpi); p = lp->lp_slang->sl_regions; if (p[0] != 0) { @@ -12156,9 +12294,12 @@ ex_spelldump(eap) /* * Loop over all files loaded for the entries in 'spelllang'. */ - for (lp = LANGP_ENTRY(buf->b_langp, 0); lp->lp_slang != NULL; ++lp) + for (lpi = 0; lpi < buf->b_langp.ga_len; ++lpi) { + lp = LANGP_ENTRY(buf->b_langp, lpi); slang = lp->lp_slang; + if (slang->sl_fbyts == NULL) /* reloading failed */ + continue; vim_snprintf((char *)IObuff, IOSIZE, "# file: %s", slang->sl_fname); ml_append(lnum++, IObuff, (colnr_T)0, FALSE); @@ -12205,6 +12346,7 @@ ex_spelldump(eap) * Only use the word when the region matches. */ flags = (int)idxs[n]; if ((round == 2 || (flags & WF_KEEPCAP) == 0) + && (flags & WF_NEEDCOMP) == 0 && (do_region || (flags & WF_REGION) == 0 || (((unsigned)flags >> 16) @@ -12222,7 +12364,7 @@ ex_spelldump(eap) /* Apply the prefix, if there is one. */ if (c != 0) - lnum = apply_prefixes(slang, word, round, + lnum = dump_prefixes(slang, word, round, flags, lnum); } } @@ -12302,7 +12444,7 @@ dump_word(word, round, flags, lnum) * Return the updated line number. */ static linenr_T -apply_prefixes(slang, word, round, flags, startlnum) +dump_prefixes(slang, word, round, flags, startlnum) slang_T *slang; char_u *word; /* case-folded word */ int round; diff --git a/src/testdir/test58.in b/src/testdir/test58.in index 530b27a05..8bb58bfee 100644 --- a/src/testdir/test58.in +++ b/src/testdir/test58.in @@ -6,63 +6,50 @@ STARTTEST :" Don't want to depend on the locale from the environment :set enc=latin1 :e! -:" First generate a .spl file from a .dic and a .aff file. -gg:/^affstart1/+1,/^affend1/-1w! Xtest.aff -gg:/^dicstart/+1,/^dicend/-1w! Xtest.dic -:mkspell! Xtest Xtest :" -:" use that spell file -:set spl=Xtest.latin1.spl -:set spell -:func SpellTest() -/^test1: -normal ]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 4) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) +:" Function to test .aff/.dic with list of good and bad words. +:func TestOne(aff, dic) + set spellfile= + $put ='' + $put ='test '. a:aff . '-' . a:dic + " Generate a .spl file from a .dic and .aff file. + exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff' + exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic' + mkspell! Xtest Xtest + " use that spell file + set spl=Xtest.latin1.spl spell + " list all valid words + spelldump + %yank + quit + $put + $put ='-------' + " find all bad words and suggestions for them + exe '1;/^' . a:aff . 'good:' + normal 0f:]s + let prevbad = '' + while 1 + let bad = spellbadword() + if bad == '' || bad == prevbad || bad == 'badend' + break + endif + let prevbad = bad + let lst = spellsuggest(bad, 3) + normal mm + $put =bad + $put =string(lst) + normal `m]s + endwhile endfunc -:call SpellTest() -:spelldump -1GyG:q -:$put +:" +:call TestOne('1', '1') :$put =soundfold('goobledygoook') :$put =soundfold('kóopërÿnôven') :$put =soundfold('oeverloos gezwets edale') :" +:" :" and now with SAL instead of SOFO items; test automatic reloading -gg:/^affstart2/+1,/^affend2/-1w! Xtest.aff +gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff :mkspell! Xtest Xtest :$put =soundfold('goobledygoook') :$put =soundfold('kóopërÿnôven') @@ -101,39 +88,16 @@ gg:/^addstart/+1,/^addend/-1w! Xtest.latin1.add :$put =str :" :" Postponed prefixes -gg:/^affstart3/+1,/^affend3/-1w! Xtest.aff -:mkspell! Xtest Xtest -:set spellfile= -:set spl=Xtest.latin1.spl -:spelldump -1GyG:q -:$put -:call SpellTest() +:call TestOne('2', '1') :" -:" Compounding -gg:/^compaffstart/+1,/^compaffend/-1w! Xtest.aff -gg:/^compdicstart/+1,/^compdicend/-1w! Xtest.dic -:mkspell! Xtest Xtest -:set spellfile= -:set spl=Xtest.latin1.spl -:spelldump -1GyG:q -:$put -/^comptest: -:for i in range(11) -normal ]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 3) -$put =string(lst) -normal `m -endfor +:" Compound words +:call TestOne('3', '3') +:call TestOne('4', '4') :" gg:/^test output:/,$wq! test.out ENDTEST -affstart1 +1affstart SET ISO8859-1 TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ @@ -182,9 +146,27 @@ MAP nñ MAP cç MAP yÿý MAP sß -affend1 +1affend + +1good: wrong OK puts. Test the end +bad: inputs comment ok Ok. test déôl end the +badend + +1dicstart +123456 +test/NO +# comment +wrong +Comment +OK +uk +put/ISO +the end +deol +déôr +1dicend -affstart2 +affstart_sal SET ISO8859-1 TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ @@ -338,9 +320,9 @@ SAL X KS SAL Y(AEIOU)- Y SAL ZZ- _ SAL Z S -affend2 +affend_sal -affstart3 +2affstart SET ISO8859-1 FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ @@ -387,23 +369,47 @@ MAP nñ MAP cç MAP yÿý MAP sß -affend3 +2affend -dicstart -123456 -test/NO -# comment -wrong -Comment -OK -uk -put/ISO -the end -deol -déôr -dicend +2good: puts +bad: inputs comment ok Ok end the. test déôl +badend -compaffstart +addstart +/regions=usgbnz +elequint/2 +elekwint/3 +addend + +test2: +elequint test elekwint test elekwent asdf + +Test rules for compounding. + +3affstart +SET ISO8859-1 + +COMPOUNDMIN 3 +COMPOUNDFLAGS m* +NEEDCOMPOUND x +3affend + +3dicstart +1234 +foo/m +bar/mx +mï/m +la/mx +3dicend + +3good: foo mï foobar foofoobar barfoo barbarfoo +bad: bar la foomï barmï mïfoo mïbar mïmï lala mïla lamï foola labar +badend + + +Tests for compounding. + +4affstart SET ISO8859-1 FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ @@ -445,9 +451,9 @@ SFX a 0 ize . nocomp PFX p N 1 PFX p 0 pre . -compaffend +4affend -compdicstart +4dicstart 1234 word/m util/am @@ -456,37 +462,16 @@ tomato/m bork/mp start/s end/e -compdicend - -addstart -/regions=usgbnz -elequint/2 -elekwint/3 -addend - -test1: -inputs wrong -comment wrong -puts OK -ok wrong -Ok wrong -the end. test wrong -déôl - -test2: -elequint test elekwint test elekwent asdf - -comptest: -word util -wordutil wordutils wordutilize -pro pro-ok -bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork -borkborkborkborkborkbork -tomato tomatotomato tomatotomatotomato -startend endstart endend startstart wordend -startword startwordword wordstart startwordend startwordwordend -startwordwordwordend startwordwordwordwordend -prebork preborkprebork preborkborkprebork preborkpreborkbork -borkpreborkpreborkbork +4dicend + +4good: word util bork prebork start end wordutil wordutils pro-ok + bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork + tomato tomatotomato startend startword startwordword startwordend + startwordwordend startwordwordwordend prebork preborkprebork + preborkborkprebork preborkpreborkbork +bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato + endstart endend startstart wordend wordstart + startwordwordwordwordend borkpreborkpreborkbork +badend test output: diff --git a/src/testdir/test58.ok b/src/testdir/test58.ok index 570ab7d7e..67f1f9cac 100644 --- a/src/testdir/test58.ok +++ b/src/testdir/test58.ok @@ -1,16 +1,6 @@ test output: -inputs -['input', 'puts', 'outputs', 'put'] -comment -['Comment'] -ok -['OK', 'uk'] -Ok -['OK', 'Uk'] -test -['test', 'Test'] -déôl -['deol', 'déôr'] + +test 1-1 # file: Xtest.latin1.spl Comment deol @@ -28,6 +18,25 @@ testn the end uk wrong +------- +bad +['put', 'OK', 'uk'] +inputs +['input', 'puts', 'outputs'] +comment +['Comment'] +ok +['OK', 'uk', 'put'] +Ok +['OK', 'Uk', 'Put'] +test +['test', 'Test', 'testn'] +déôl +['deol', 'déôr', 'test'] +end +['put', 'test', 'uk'] +the +['put', 'uk', 'test'] gebletegek kepereneven everles gesvets etele @@ -43,6 +52,8 @@ elequint elekwent elequint elekwint + +test 2-1 # file: Xtest.latin1.spl Comment deol @@ -60,18 +71,59 @@ testn the end uk wrong +------- +bad +['put', 'uk', 'OK'] inputs -['input', 'puts', 'put', 'outputs'] +['input', 'puts', 'put'] comment ['Comment'] ok -['OK', 'uk'] +['OK', 'uk', 'put'] Ok -['OK', 'Uk'] +['OK', 'Uk', 'Put'] +end +['put', 'uk', 'deol'] +the +['put', 'uk', 'test'] test -['test', 'Test'] +['test', 'Test', 'testn'] déôl -['deol', 'déôr'] +['deol', 'déôr', 'test'] + +test 3-3 +# file: Xtest.latin1.spl +foo +mï +------- +bad +['foo', 'mï'] +bar +['foobar', 'foo', 'mï'] +la +['mï', 'foo'] +foomï +['foo mï', 'foo', 'foofoo'] +barmï +['bar mï', 'barfoo', 'barbar'] +mïfoo +['mï foo', 'foo', 'foofoo'] +mïbar +['foobar', 'barbar', 'mï'] +mïmï +['mï mï', 'mï', 'la mï'] +lala +['la mï'] +mïla +['mï', 'mï mï'] +lamï +['la mï', 'mï', 'mï mï'] +foola +['foo', 'foobar', 'foofoo'] +labar +['barbar', 'foobar'] + +test 4-4 # file: Xtest.latin1.spl bork prebork @@ -83,6 +135,9 @@ util utilize utils word +------- +bad +['end', 'bork', 'word'] wordutilize ['word utilize', 'wordutils', 'wordutil'] pro diff --git a/src/testdir/test59.in b/src/testdir/test59.in index a49514fa5..aab48aeea 100644 --- a/src/testdir/test59.in +++ b/src/testdir/test59.in @@ -8,65 +8,52 @@ STARTTEST :" text is in latin1, the test text is utf-8. :set enc=latin1 :e! -:set fenc= -:" First generate a .spl file from a .dic and a .aff file. -gg:/^affstart1/+1,/^affend1/-1w! Xtest.aff -gg:/^dicstart/+1,/^dicend/-1w! Xtest.dic :set enc=utf-8 -:mkspell! Xtest Xtest +:set fenc= :" -:" use that spell file -:set spl=Xtest.utf-8.spl -:set spell -:func SpellTest() -/^test1: -normal ]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 4) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) -normal `m]smm -let str = spellbadword() -$put =str -normal `m -let lst = spellsuggest(str, 2) -$put =string(lst) +:" Function to test .aff/.dic with list of good and bad words. +:func TestOne(aff, dic) + set spellfile= + $put ='' + $put ='test '. a:aff . '-' . a:dic + " Generate a .spl file from a .dic and .aff file. + exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff' + exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic' + mkspell! Xtest Xtest + " use that spell file + set spl=Xtest.utf-8.spl spell + " list all valid words + spelldump + %yank + quit + $put + $put ='-------' + " find all bad words and suggestions for them + exe '1;/^' . a:aff . 'good:' + normal 0f:]s + let prevbad = '' + while 1 + let bad = spellbadword() + if bad == '' || bad == prevbad || bad == 'badend' + break + endif + let prevbad = bad + let lst = spellsuggest(bad, 3) + normal mm + $put =bad + $put =string(lst) + normal `m]s + endwhile endfunc -:call SpellTest() -:spelldump -1GyG:q -:$put +:" +:call TestOne('1', '1') :$put =soundfold('goobledygoook') :$put =soundfold('kóopërÿnôven') :$put =soundfold('oeverloos gezwets edale') :" +:" :" and now with SAL instead of SOFO items; test automatic reloading -gg:/^affstart2/+1,/^affend2/-1w! Xtest.aff +gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff :mkspell! Xtest Xtest :$put =soundfold('goobledygoook') :$put =soundfold('kóopërÿnôven') @@ -105,20 +92,16 @@ gg:/^addstart/+1,/^addend/-1w! Xtest.utf-8.add :$put =str :" :" Postponed prefixes -gg:/^affstart3/+1,/^affend3/-1w! Xtest.aff -:mkspell! Xtest Xtest -:set spellfile= -:set spl=Xtest.utf-8.spl -:mess -:spelldump -1GyG:q -:$put -:call SpellTest() +:call TestOne('2', '1') +:" +:" Compound words +:call TestOne('3', '3') +:call TestOne('4', '4') :" gg:/^test output:/,$wq! test.out ENDTEST -affstart1 +1affstart SET ISO8859-1 TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ @@ -167,9 +150,9 @@ MAP nñ MAP cç MAP yÿý MAP sß -affend1 +1affend -affstart2 +affstart_sal SET ISO8859-1 TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ @@ -323,9 +306,9 @@ SAL X KS SAL Y(AEIOU)- Y SAL ZZ- _ SAL Z S -affend2 +affend_sal -affstart3 +2affstart SET ISO8859-1 FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ @@ -372,9 +355,9 @@ MAP nñ MAP cç MAP yÿý MAP sß -affend3 +2affend -dicstart +1dicstart 123456 test/NO # comment @@ -386,7 +369,7 @@ put/ISO the end deol déôr -dicend +1dicend addstart /regions=usgbnz @@ -394,17 +377,105 @@ elequint/2 elekwint/3 addend -test1: -inputs wrong -comment wrong -puts OK -ok wrong -Ok wrong -the end. test wrong -déôl +1good: wrong OK puts. Test the end +bad: inputs comment ok Ok. test déôl end the +badend + +2good: puts +bad: inputs comment ok Ok end the. test déôl +badend + +Test rules for compounding. + +3affstart +SET ISO8859-1 + +COMPOUNDMIN 3 +COMPOUNDFLAGS m* +NEEDCOMPOUND x +3affend + +3dicstart +1234 +foo/m +bar/mx +mï/m +la/mx +3dicend + +3good: foo mï foobar foofoobar barfoo barbarfoo +bad: bar la foomï barmï mïfoo mïbar mïmï lala mïla lamï foola labar +badend + + +Tests for compounding. + +4affstart +SET ISO8859-1 + +FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ +LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ +UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ + +COMPOUNDFLAGS m+ +COMPOUNDFLAGS sm*e +COMPOUNDFLAGS sm+ +COMPOUNDMIN 3 +COMPOUNDMAX 3 + +COMPOUNDSYLMAX 5 +SYLLABLE aáeéiíoóöõuúüûy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui + +MAP 9 +MAP aàáâãäå +MAP eèéêë +MAP iìíîï +MAP oòóôõö +MAP uùúûü +MAP nñ +MAP cç +MAP yÿý +MAP sß + +NEEDAFFIX x + +PFXPOSTPONE + +MIDWORD '- + +SFX q N 1 +SFX q 0 -ok . + +SFX a Y 2 +SFX a 0 s . +SFX a 0 ize . nocomp + +PFX p N 1 +PFX p 0 pre . +4affend + +4dicstart +1234 +word/m +util/am +pro/xq +tomato/m +bork/mp +start/s +end/e +4dicend + +4good: word util bork prebork start end wordutil wordutils pro-ok + bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork + tomato tomatotomato startend startword startwordword startwordend + startwordwordend startwordwordwordend prebork preborkprebork + preborkborkprebork preborkpreborkbork +bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato + endstart endend startstart wordend wordstart + startwordwordwordwordend borkpreborkpreborkbork +badend test2: elequint test elekwint test elekwent asdf - test output: diff --git a/src/testdir/test59.ok b/src/testdir/test59.ok index 6bbed6e22..e09eaaceb 100644 --- a/src/testdir/test59.ok +++ b/src/testdir/test59.ok @@ -1,16 +1,6 @@ test output: -inputs -['input', 'puts', 'outputs', 'put'] -comment -['Comment'] -ok -['OK', 'uk'] -Ok -['OK', 'Uk'] -test -['test', 'Test'] -déôl -['deol', 'déôr'] + +test 1-1 # file: Xtest.utf-8.spl Comment deol @@ -28,6 +18,25 @@ testn the end uk wrong +------- +bad +['put', 'OK', 'uk'] +inputs +['input', 'puts', 'outputs'] +comment +['Comment'] +ok +['OK', 'uk', 'put'] +Ok +['OK', 'Uk', 'Put'] +test +['test', 'Test', 'testn'] +déôl +['deol', 'déôr', 'test'] +end +['put', 'test', 'uk'] +the +['put', 'uk', 'test'] gebletegek kepereneven everles gesvets etele @@ -43,6 +52,8 @@ elequint elekwent elequint elekwint + +test 2-1 # file: Xtest.utf-8.spl Comment deol @@ -60,15 +71,92 @@ testn the end uk wrong +------- +bad +['put', 'uk', 'OK'] inputs -['input', 'puts', 'put', 'outputs'] +['input', 'puts', 'put'] comment ['Comment'] ok -['OK', 'uk'] +['OK', 'uk', 'put'] Ok -['OK', 'Uk'] +['OK', 'Uk', 'Put'] +end +['put', 'uk', 'deol'] +the +['put', 'uk', 'test'] test -['test', 'Test'] +['test', 'Test', 'testn'] déôl -['deol', 'déôr'] +['deol', 'déôr', 'test'] + +test 3-3 +# file: Xtest.utf-8.spl +foo +mï +------- +bad +['foo', 'mï'] +bar +['foobar', 'foo', 'mï'] +la +['foo', 'mï'] +foomï +['foo mï', 'foo', 'foofoo'] +barmï +['bar mï', 'barfoo', 'barbar'] +mïfoo +['mï foo', 'foo', 'foofoo'] +mïbar +['foobar', 'barbar', 'mï'] +mïmï +['mï mï', 'mï', 'la mï'] +lala +[] +mïla +['mï'] +lamï +['la mï', 'mï', 'mï mï'] +foola +['foo', 'foobar', 'foofoo'] +labar +['barbar', 'foobar'] + +test 4-4 +# file: Xtest.utf-8.spl +bork +prebork +end +pro-ok +start +tomato +util +utilize +utils +word +------- +bad +['end', 'bork', 'word'] +wordutilize +['word utilize', 'wordutils', 'wordutil'] +pro +['bork', 'end', 'word'] +borkborkborkborkborkbork +['borkbork borkborkborkbork', 'borkborkbork borkborkbork', 'borkborkborkborkbork bork'] +tomatotomatotomato +['tomato tomatotomato', 'tomatotomato tomato', 'tomato tomato tomato'] +endstart +['end start', 'start'] +endend +['end end', 'end'] +startstart +['start start'] +wordend +['word end', 'wordword', 'word'] +wordstart +['word start', 'bork start'] +startwordwordwordwordend +['startwordwordwordword end', 'startwordwordwordword', 'start wordwordwordword end'] +borkpreborkpreborkbork +['borkpreborkprebork bork', 'borkprebork preborkbork', 'bork preborkpreborkbork'] diff --git a/src/version.h b/src/version.h index 13e407156..2317c87a2 100644 --- a/src/version.h +++ b/src/version.h @@ -36,5 +36,5 @@ #define VIM_VERSION_NODOT "vim70aa" #define VIM_VERSION_SHORT "7.0aa" #define VIM_VERSION_MEDIUM "7.0aa ALPHA" -#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 26)" -#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 26, compiled " +#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 29)" +#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Aug 29, compiled " |