1
0
forked from aniani/vim

updated for version 7.0099

This commit is contained in:
Bram Moolenaar
2005-07-01 22:33:52 +00:00
parent 505e82870e
commit 7887d88a9f
4 changed files with 471 additions and 370 deletions

View File

@@ -1,7 +1,7 @@
" These commands create the option window.
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2005 Mar 07
" Last Change: 2005 Jul 01
" If there already is an option window, jump to that one.
if bufwinnr("option-window") > 0
@@ -368,7 +368,7 @@ if has("linebreak")
endif
call <SID>Header("syntax and highlighting")
call <SID>Header("syntax, highlighting and spelling")
call append("$", "background\t\"dark\" or \"light\"; the background color brightness")
call <SID>OptionG("bg", &bg)
if has("autocmd")
@@ -385,6 +385,19 @@ call append("$", "highlight\twhich highlighting to use for various occasions")
call <SID>OptionG("hl", &hl)
call append("$", "hlsearch\thighlight all matches for the last used search pattern")
call <SID>BinOptionG("hls", &hls)
if has("syntax")
call append("$", "spell\thighlight spelling mistakes")
call append("$", "\t(local to window)")
call <SID>BinOptionL("spell")
call append("$", "spelllang\tlist of accepted languages")
call append("$", "\t(local to buffer)")
call <SID>OptionL("spl")
call append("$", "spellfile\tfile that \"zg\" adds good words to")
call append("$", "\t(local to buffer)")
call <SID>OptionL("spf")
call append("$", "spellsuggest\tmethods used to suggest corrections")
call <SID>OptionG("sps", &sps)
endif
call <SID>Header("multiple windows")
@@ -614,6 +627,8 @@ call append("$", "report\tthreshold for reporting number of changed lines")
call append("$", " \tset report=" . &report)
call append("$", "verbose\tthe higher the more messages are given")
call append("$", " \tset vbs=" . &vbs)
call append("$", "verbosefile\tfile to write messages in")
call <SID>OptionG("vfile", &vfile)
call append("$", "more\tpause listings when the screen is full")
call <SID>BinOptionG("more", &more)
if has("dialog_con") || has("dialog_gui")

View File

@@ -3,74 +3,101 @@
# It builds on Windows 95 and all four NT platforms: i386, Alpha, MIPS, and
# PowerPC. The NT/i386 binary and the Windows 95 binary are identical.
#
# To build using Borland C++, use Make_bc3.mak or Make_bc5.mak.
#
# This makefile can build the console, GUI, OLE-enable, Perl-enabled and
# Python-enabled versions of vim for Win32 platforms.
#
# When compiling different versions, do "nmake clean" first!
#
# The basic command line to build vim is:
#
# nmake -f Make_mvc.mak
#
# This will build the console version of vim with no additional interfaces.
# To add interfaces, define any of the following:
# To add features, define any of the following:
#
# !!!! After changing features do "nmake clean" first !!!!
#
# Feature Set: FEATURES=[TINY, SMALL, NORMAL, BIG, HUGE] (default is BIG)
#
# GUI interface: GUI=yes (default is no)
#
# OLE interface: OLE=yes (usually with GUI=yes)
#
# Multibyte support: MBYTE=yes
#
# IME support: IME=yes (requires GUI=yes)
# DYNAMIC_IME=[yes or no] (to load the imm32.dll dynamically, default
# is yes)
# Global IME support: GIME=yes (requires GUI=yes)
#
# MzScheme interface:
# MZSCHEME=[Path to MzScheme directory]
# DYNAMIC_MZSCHEME=yes (to load the MzScheme DLLs dynamically)
# MZSCHEME_VER=[version, 205_000, ...]
#
# Perl interface:
# PERL=[Path to Perl directory]
# DYNAMIC_PERL=yes (to load the Perl DLL dynamically)
# PERL_VER=[Perl version, in the form 55 (5.005), 56 (5.6.x), etc] (default is 56)
# PERL_VER=[Perl version, in the form 55 (5.005), 56 (5.6.x), etc]
# (default is 56)
#
# Python interface:
# PYTHON=[Path to Python directory]
# DYNAMIC_PYTHON=yes (to load the Python DLL dynamically)
# PYTHON_VER=[Python version, eg 15, 20] (default is 22)
#
# Ruby interface:
# RUBY=[Path to Ruby directory]
# DYNAMIC_RUBY=yes (to load the Ruby DLL dynamically)
# RUBY_VER=[Ruby version, eg 16, 17] (default is 18)
# RUBY_VER_LONG=[Ruby version, eg 1.6, 1.7] (default is 1.8)
# You must set RUBY_VER_LONG when change RUBY_VER.
#
# Tcl interface:
# TCL=[Path to Tcl directory]
# DYNAMIC_TCL=yes (to load the Tcl DLL dynamically)
# TCL_VER=[Tcl version, e.g. 80, 83] (default is 83)
# TCL_VER_LONG=[Tcl version, eg 8.3] (default is 8.3)
# You must set TCL_VER_LONG when you set TCL_VER.
#
# SNiFF+ interface: SNIFF=yes
#
# Cscope support: CSCOPE=yes
#
# Iconv library support (always dynamically loaded):
# ICONV=[yes or no] (default is yes)
#
# Intl library support (always dynamically loaded):
# GETTEXT=[yes or no] (default is yes)
# See http://sourceforge.net/projects/gettext/
#
# PostScript printing: POSTSCRIPT=yes (default is no)
#
# Netbeans Support: NETBEANS=[yes or no] (default is yes if GUI is yes)
#
# XPM Image Support: XPM=[path to XPM directory]
#
# Optimization: OPTIMIZE=[SPACE, SPEED, MAXSPEED] (default is MAXSPEED)
#
# Processor Version: CPUNR=[i386, i486, i586, i686, pentium4] (default is
# i386)
#
# Version Support: WINVER=[0x0400, 0x0500] (default is 0x0400)
#
# Debug version: DEBUG=yes
# Mapfile: MAP=[no, yes or lines] (default is yes)
# no: Don't write a mapfile.
# yes: Write a normal mapfile.
# lines: Write a mapfile with line numbers (only for VC6 and later)
# SNiFF+ interface: SNIFF=yes
# Cscope support: CSCOPE=yes
# Iconv library support (always dynamically loaded):
# ICONV=[yes or no] (default is yes)
# Intl library support (always dynamically loaded):
# GETTEXT=[yes or no] (default is yes)
# See http://sourceforge.net/projects/gettext/
# PostScript printing: POSTSCRIPT=yes (default is no)
# Feature Set: FEATURES=[TINY, SMALL, NORMAL, BIG, HUGE] (default is BIG)
# Version Support: WINVER=[0x0400, 0x0500] (default is 0x0400)
# Processor Version: CPUNR=[i386, i486, i586, i686, pentium4] (default is i386)
# Optimization: OPTIMIZE=[SPACE, SPEED, MAXSPEED] (default is MAXSPEED)
# Netbeans Support: NETBEANS=[yes or no] (default is yes if GUI is yes)
# Netbeans Debugging Support: NBDEBUG=[yes or no] (default is no)
# XPM Image Support: XPM=[path to XPM directory]
#
# Netbeans Debugging Support: NBDEBUG=[yes or no] (should be no, yes
# doesn't work)
#
# You can combine any of these interfaces
#
# Example: To build the non-debug, GUI version with Perl interface:
# nmake -f Make_mvc.mak GUI=yes PERL=C:\Perl
#
# To build using Borland C++, use Make_bc3.mak or Make_bc5.mak.
#
# DEBUG with Make_mvc.mak and Make_dvc.mak:
# This makefile gives a fineness of control which is not supported in
# Visual C++ configuration files. Therefore, debugging requires a bit of

View File

@@ -4665,6 +4665,8 @@ dozet:
#ifdef FEAT_SYN_HL
case 'g': /* "zg": add good word to word list */
case 'w': /* "zw": add wrong word to word list */
case 'G': /* "zG": add good word to temp word list */
case 'W': /* "zW": add wrong word to temp word list */
{
char_u *ptr = NULL;
int len;
@@ -4679,7 +4681,8 @@ dozet:
if (ptr == NULL && (len = find_ident_under_cursor(&ptr,
FIND_IDENT)) == 0)
return;
spell_add_word(ptr, len, nchar == 'w');
spell_add_word(ptr, len, nchar == 'w' || nchar == 'W',
nchar == 'G' || nchar == 'W');
}
break;

View File

@@ -377,6 +377,9 @@ typedef struct langp_S
#define VIMSPELLMAGIC "VIMspell08" /* string at start of Vim spell file */
#define VIMSPELLMAGICL 10
/* file used for "zG" and "zW" */
static char_u *temp_wordlist = NULL;
/*
* Information used when looking for suggestions.
*/
@@ -574,10 +577,6 @@ typedef struct trystate_S
#define FIND_KEEPWORD 1 /* find keep-case word */
#define FIND_PREFIX 2 /* find word after prefix */
/* values for read_cnt_string() */
#define ERR_NOMEM -1
#define ERR_TRUNC -2
static slang_T *slang_alloc __ARGS((char_u *lang));
static void slang_free __ARGS((slang_T *lp));
static void slang_clear __ARGS((slang_T *lp));
@@ -592,6 +591,8 @@ static char_u *spell_enc __ARGS((void));
static void spell_load_cb __ARGS((char_u *fname, void *cookie));
static slang_T *spell_load_file __ARGS((char_u *fname, char_u *lang, slang_T *old_lp, int silent));
static char_u *read_cnt_string __ARGS((FILE *fd, int cnt_bytes, int *errp));
static int set_sofo __ARGS((slang_T *lp, char_u *from, char_u *to));
static void set_sal_first __ARGS((slang_T *lp));
#ifdef FEAT_MBYTE
static int *mb_str2wide __ARGS((char_u *s));
#endif
@@ -601,7 +602,7 @@ static void use_midword __ARGS((slang_T *lp, buf_T *buf));
static int find_region __ARGS((char_u *rp, char_u *region));
static int captype __ARGS((char_u *word, char_u *end));
static void spell_reload_one __ARGS((char_u *fname, int added_word));
static int set_spell_charflags __ARGS((char_u *flags, int cnt, char_u *upp));
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));
@@ -683,6 +684,7 @@ static linenr_T apply_prefixes __ARGS((slang_T *slang, char_u *word, int round,
static char *e_format = N_("E759: Format error in spell file");
static char *e_spell_trunc = N_("E758: Truncated spell file");
/*
* Main spell-checking function.
@@ -1690,9 +1692,7 @@ spell_load_file(fname, lang, old_lp, silent)
garray_T *gap;
fromto_T *ftp;
salitem_T *smp;
int rr;
short *first;
salfirst_T *sfirst;
idx_T idx;
int c = 0;
@@ -1756,7 +1756,7 @@ spell_load_file(fname, lang, old_lp, silent)
if (cnt < 0)
{
truncerr:
EMSG(_("E758: Truncated spell file"));
EMSG(_(e_spell_trunc));
goto endFAIL;
}
if (cnt > 8)
@@ -1772,48 +1772,33 @@ formerr:
}
lp->sl_regions[cnt * 2] = NUL;
cnt = getc(fd); /* <charflagslen> */
if (cnt > 0)
{
p = alloc((unsigned)cnt);
if (p == NULL)
/* <charflagslen> <charflags> */
p = read_cnt_string(fd, 1, &cnt);
if (cnt == FAIL)
goto endFAIL;
for (i = 0; i < cnt; ++i)
p[i] = getc(fd); /* <charflags> */
/* <fcharslen> <fchars> */
fol = read_cnt_string(fd, 2, &ccnt);
if (ccnt != 0)
fol = read_cnt_string(fd, 2, &cnt);
if (cnt == FAIL)
{
vim_free(p);
if (ccnt == ERR_NOMEM)
goto endFAIL;
if (ccnt == ERR_TRUNC)
goto formerr;
}
/* Set the word-char flags and fill SPELL_ISUPPER() table. */
i = set_spell_charflags(p, cnt, fol);
if (p != NULL && fol != NULL)
i = set_spell_charflags(p, fol);
vim_free(p);
vim_free(fol);
#if 0 /* tolerate the differences */
if (i == FAIL)
goto formerr;
#endif
}
else
{
/* When <charflagslen> is zero then <fcharlen> must also be zero. */
cnt = (getc(fd) << 8) + getc(fd);
if (cnt != 0)
if ((p == NULL) != (fol == NULL))
goto formerr;
}
/* <midwordlen> <midword> */
lp->sl_midword = read_cnt_string(fd, 2, &cnt);
if (cnt == ERR_TRUNC)
goto truncerr;
if (cnt == ERR_NOMEM)
if (cnt == FAIL)
goto endFAIL;
/* <prefcondcnt> <prefcond> ... */
@@ -1863,29 +1848,15 @@ formerr:
for (; gap->ga_len < cnt; ++gap->ga_len)
{
ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
for (rr = 1; rr <= 2; ++rr)
ftp->ft_from = read_cnt_string(fd, 1, &i);
if (i == FAIL)
goto endFAIL;
ftp->ft_to = read_cnt_string(fd, 1, &i);
if (i == FAIL)
{
ccnt = getc(fd);
if (ccnt < 0)
{
if (rr == 2)
vim_free(ftp->ft_from);
goto formerr;
}
if ((p = alloc(ccnt + 1)) == NULL)
{
if (rr == 2)
vim_free(ftp->ft_from);
goto endFAIL;
}
for (i = 0; i < ccnt; ++i)
p[i] = getc(fd); /* <repfrom> or <repto> */
p[i] = NUL;
if (rr == 1)
ftp->ft_from = p;
else
ftp->ft_to = p;
}
}
/* Fill the first-index table. */
@@ -1921,118 +1892,27 @@ formerr:
if (cnt != 1)
goto formerr;
cnt = (getc(fd) << 8) + getc(fd); /* <salfromlen> */
if (cnt < 0)
goto formerr;
if ((bp = alloc(cnt + 1)) == NULL)
/* <salfromlen> <salfrom> */
bp = read_cnt_string(fd, 2, &cnt);
if (cnt == FAIL)
goto endFAIL;
for (i = 0; i < cnt; ++i)
bp[i] = getc(fd); /* <salfrom> */
bp[i] = NUL;
ccnt = (getc(fd) << 8) + getc(fd); /* <saltolen> */
if (ccnt < 0)
{
vim_free(bp);
goto formerr;
}
if ((fol = alloc(ccnt + 1)) == NULL)
/* <saltolen> <salto> */
fol = read_cnt_string(fd, 2, &cnt);
if (cnt == FAIL)
{
vim_free(bp);
goto endFAIL;
}
for (i = 0; i < ccnt; ++i)
fol[i] = getc(fd); /* <salto> */
fol[i] = NUL;
#ifdef FEAT_MBYTE
if (has_mbyte)
{
char_u *s;
/* Store the info in lp->sl_sal and/or lp->sl_sal_first. */
i = set_sofo(lp, bp, fol);
/* Use "sl_sal" as an array with 256 pointers to a list of wide
* characters. The index is the low byte of the character.
* The list contains from-to pairs with a terminating NUL.
* sl_sal_first[] is used for latin1 "from" characters. */
gap = &lp->sl_sal;
ga_init2(gap, sizeof(int *), 1);
if (ga_grow(gap, 256) == FAIL)
{
sofoFAIL:
vim_free(bp);
vim_free(fol);
goto endFAIL;
}
vim_memset(gap->ga_data, 0, sizeof(int *) * 256);
gap->ga_len = 256;
/* First count the number of items for each list. Temporarily use
* sl_sal_first[] for this. */
for (p = bp, s = fol; *p != NUL && *s != NUL; )
{
c = mb_ptr2char_adv(&p);
mb_ptr_adv(s);
if (c >= 256)
++lp->sl_sal_first[c & 0xff];
}
if (*p != NUL || *s != NUL) /* lengths differ */
goto sofoerr;
/* Allocate the lists. */
for (i = 0; i < 256; ++i)
if (lp->sl_sal_first[i] > 0)
{
p = alloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
if (p == NULL)
goto sofoFAIL;
((int **)gap->ga_data)[i] = (int *)p;
*(int *)p = 0;
}
/* Put the characters in sl_sal_first[] or a sl_sal list. */
vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
for (p = bp, s = fol; *p != NUL && *s != NUL; )
{
c = mb_ptr2char_adv(&p);
i = mb_ptr2char_adv(&s);
if (c >= 256)
{
int *inp;
/* Append the from-to chars at the end of the list with
* the low byte. */
inp = ((int **)gap->ga_data)[c & 0xff];
while (*inp != 0)
++inp;
*inp++ = c; /* from char */
*inp++ = i; /* to char */
*inp++ = NUL; /* NUL at the end */
}
else
/* mapping byte to char is done in sl_sal_first[] */
lp->sl_sal_first[c] = i;
}
}
else
#endif
{
/* mapping bytes to bytes is done in sl_sal_first[] */
if (cnt != ccnt)
{
#ifdef FEAT_MBYTE
sofoerr:
#endif
vim_free(bp);
vim_free(fol);
if (i == FAIL)
goto formerr;
}
for (i = 0; i < cnt; ++i)
lp->sl_sal_first[bp[i]] = fol[i];
lp->sl_sal.ga_len = 1; /* indicates we have soundfolding */
}
vim_free(bp);
vim_free(fol);
}
else
{
/*
@@ -2091,22 +1971,13 @@ sofoerr:
*p++ = getc(fd); /* <salfrom> */
*p++ = NUL;
ccnt = getc(fd); /* <saltolen> */
if (ccnt < 0)
/* <saltolen> <salto> */
smp->sm_to = read_cnt_string(fd, 1, &ccnt);
if (ccnt == FAIL)
{
vim_free(smp->sm_lead);
goto formerr;
}
if ((p = alloc(ccnt + 1)) == NULL)
{
vim_free(smp->sm_lead);
goto endFAIL;
}
smp->sm_to = p;
for (i = 0; i < ccnt; ++i)
*p++ = getc(fd); /* <salto> */
*p++ = NUL;
#ifdef FEAT_MBYTE
if (has_mbyte)
@@ -2135,64 +2006,13 @@ sofoerr:
}
/* Fill the first-index table. */
sfirst = lp->sl_sal_first;
for (i = 0; i < 256; ++i)
sfirst[i] = -1;
smp = (salitem_T *)gap->ga_data;
for (i = 0; i < gap->ga_len; ++i)
{
#ifdef FEAT_MBYTE
if (has_mbyte)
/* Use the lowest byte of the first character. For latin1 it's
* the character, for other encodings it should differ for most
* characters. */
c = *smp[i].sm_lead_w & 0xff;
else
#endif
c = *smp[i].sm_lead;
if (sfirst[c] == -1)
{
sfirst[c] = i;
#ifdef FEAT_MBYTE
if (has_mbyte)
{
/* Make sure all entries with this byte are following each
* other. Move the ones that are in the wrong position. Do
* keep the same ordering! */
while (i + 1 < gap->ga_len
&& (*smp[i + 1].sm_lead_w & 0xff) == c)
/* Skip over entry with same index byte. */
++i;
for (n = 1; i + n < gap->ga_len; ++n)
if ((*smp[i + n].sm_lead_w & 0xff) == c)
{
salitem_T tsal;
/* Move entry with same index byte after the entries
* we already found. */
++i;
--n;
tsal = smp[i + n];
mch_memmove(smp + i + 1, smp + i,
sizeof(salitem_T) * n);
smp[i] = tsal;
}
}
#endif
}
}
set_sal_first(lp);
}
cnt = (getc(fd) << 8) + getc(fd); /* <maplen> */
if (cnt < 0)
goto formerr;
p = alloc(cnt + 1);
if (p == NULL)
/* <maplen> <mapstr> */
p = read_cnt_string(fd, 2, &cnt);
if (cnt == FAIL)
goto endFAIL;
for (i = 0; i < cnt; ++i)
p[i] = getc(fd); /* <mapstr> */
p[i] = NUL;
set_map_str(lp, p);
vim_free(p);
@@ -2270,10 +2090,9 @@ endOK:
/*
* Read a length field from "fd" in "cnt_bytes" bytes.
* Allocate memory and read the string into it.
* Allocate memory, read the string into it and add a NUL at the end.
* Returns NULL when the count is zero.
* Sets "errp" to ERR_TRUNC when reading failed, ERR_NOMEM when out of
* memory, zero when OK.
* Sets "*errp" to FAIL when there is an error, OK otherwise.
*/
static char_u *
read_cnt_string(fd, cnt_bytes, errp)
@@ -2290,7 +2109,8 @@ read_cnt_string(fd, cnt_bytes, errp)
cnt = (cnt << 8) + getc(fd);
if (cnt < 0)
{
*errp = ERR_TRUNC;
EMSG(_(e_spell_trunc));
*errp = FAIL;
return NULL;
}
@@ -2298,10 +2118,10 @@ read_cnt_string(fd, cnt_bytes, errp)
str = alloc((unsigned)cnt + 1);
if (str == NULL)
{
*errp = ERR_NOMEM;
*errp = FAIL;
return NULL;
}
*errp = 0;
*errp = OK;
/* Read the string. Doesn't check for truncated file. */
for (i = 0; i < cnt; ++i)
@@ -2311,6 +2131,162 @@ read_cnt_string(fd, cnt_bytes, errp)
return str;
}
/*
* Set the SOFOFROM and SOFOTO items in language "lp".
* Returns FAIL when there is something wrong.
*/
static int
set_sofo(lp, from, to)
slang_T *lp;
char_u *from;
char_u *to;
{
int i;
#ifdef FEAT_MBYTE
garray_T *gap;
char_u *s;
char_u *p;
int c;
int *inp;
if (has_mbyte)
{
/* Use "sl_sal" as an array with 256 pointers to a list of wide
* characters. The index is the low byte of the character.
* The list contains from-to pairs with a terminating NUL.
* sl_sal_first[] is used for latin1 "from" characters. */
gap = &lp->sl_sal;
ga_init2(gap, sizeof(int *), 1);
if (ga_grow(gap, 256) == FAIL)
return FAIL;
vim_memset(gap->ga_data, 0, sizeof(int *) * 256);
gap->ga_len = 256;
/* First count the number of items for each list. Temporarily use
* sl_sal_first[] for this. */
for (p = from, s = to; *p != NUL && *s != NUL; )
{
c = mb_ptr2char_adv(&p);
mb_ptr_adv(s);
if (c >= 256)
++lp->sl_sal_first[c & 0xff];
}
if (*p != NUL || *s != NUL) /* lengths differ */
return FAIL;
/* Allocate the lists. */
for (i = 0; i < 256; ++i)
if (lp->sl_sal_first[i] > 0)
{
p = alloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
if (p == NULL)
return FAIL;
((int **)gap->ga_data)[i] = (int *)p;
*(int *)p = 0;
}
/* Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
* list. */
vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
for (p = from, s = to; *p != NUL && *s != NUL; )
{
c = mb_ptr2char_adv(&p);
i = mb_ptr2char_adv(&s);
if (c >= 256)
{
/* Append the from-to chars at the end of the list with
* the low byte. */
inp = ((int **)gap->ga_data)[c & 0xff];
while (*inp != 0)
++inp;
*inp++ = c; /* from char */
*inp++ = i; /* to char */
*inp++ = NUL; /* NUL at the end */
}
else
/* mapping byte to char is done in sl_sal_first[] */
lp->sl_sal_first[c] = i;
}
}
else
#endif
{
/* mapping bytes to bytes is done in sl_sal_first[] */
if (STRLEN(from) != STRLEN(to))
return FAIL;
for (i = 0; to[i] != NUL; ++i)
lp->sl_sal_first[from[i]] = to[i];
lp->sl_sal.ga_len = 1; /* indicates we have soundfolding */
}
return OK;
}
/*
* Fill the first-index table for "lp".
*/
static void
set_sal_first(lp)
slang_T *lp;
{
salfirst_T *sfirst;
int i;
salitem_T *smp;
int c;
garray_T *gap = &lp->sl_sal;
sfirst = lp->sl_sal_first;
for (i = 0; i < 256; ++i)
sfirst[i] = -1;
smp = (salitem_T *)gap->ga_data;
for (i = 0; i < gap->ga_len; ++i)
{
#ifdef FEAT_MBYTE
if (has_mbyte)
/* Use the lowest byte of the first character. For latin1 it's
* the character, for other encodings it should differ for most
* characters. */
c = *smp[i].sm_lead_w & 0xff;
else
#endif
c = *smp[i].sm_lead;
if (sfirst[c] == -1)
{
sfirst[c] = i;
#ifdef FEAT_MBYTE
if (has_mbyte)
{
int n;
/* Make sure all entries with this byte are following each
* other. Move the ones that are in the wrong position. Do
* keep the same ordering! */
while (i + 1 < gap->ga_len
&& (*smp[i + 1].sm_lead_w & 0xff) == c)
/* Skip over entry with same index byte. */
++i;
for (n = 1; i + n < gap->ga_len; ++n)
if ((*smp[i + n].sm_lead_w & 0xff) == c)
{
salitem_T tsal;
/* Move entry with same index byte after the entries
* we already found. */
++i;
--n;
tsal = smp[i + n];
mch_memmove(smp + i + 1, smp + i,
sizeof(salitem_T) * n);
smp[i] = tsal;
}
}
#endif
}
}
}
#ifdef FEAT_MBYTE
/*
@@ -2472,6 +2448,7 @@ did_set_spelllang(buf)
int load_spf;
int len;
char_u *p;
int round;
ga_init2(&ga, sizeof(langp_T), 2);
clear_midword(buf);
@@ -2572,12 +2549,26 @@ did_set_spelllang(buf)
}
}
/*
* Make sure the 'spellfile' file is loaded. It may be in 'runtimepath',
* then it's probably loaded above already. Otherwise load it here.
*/
if (load_spf)
/* round 1: load 'spellfile', if needed.
* round 2: load temp_wordlist, if possible. */
for (round = 1; round <= 2; ++round)
{
if (round == 1)
{
/* Make sure the 'spellfile' file is loaded. It may be in
* 'runtimepath', then it's probably loaded above already.
* Otherwise load it here. */
if (!load_spf)
continue;
}
else
{
if (temp_wordlist == NULL)
continue;
vim_snprintf((char *)spf_name, sizeof(spf_name), "%s.%s.spl",
temp_wordlist, spell_enc());
}
/* 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)
@@ -2585,11 +2576,17 @@ did_set_spelllang(buf)
if (lp == NULL)
{
/* Not loaded, try loading it now. The language name includes the
* region name, the region is ignored otherwise. */
* region name, the region is ignored otherwise. for
* temp_wordlist use an arbitrary name. */
if (round == 1)
{
vim_strncpy(lang, gettail(buf->b_p_spf), MAXWLEN);
p = vim_strchr(lang, '.');
if (p != NULL)
*p = NUL; /* truncate at ".encoding.add" */
}
else
STRCPY(lang, "temp wordlist");
lp = spell_load_file(spf_name, lang, NULL, TRUE);
}
if (lp != NULL && ga_grow(&ga, 1) == OK)
@@ -2678,7 +2675,7 @@ use_midword(lp, buf)
/*
* Find the region "region[2]" in "rp" (points to "sl_regions").
* Each region is simply stored as the two characters of it's name.
* Returns the index if found, REGION_ALL if not found.
* Returns the index if found (first is 0), REGION_ALL if not found.
*/
static int
find_region(rp, region)
@@ -2780,6 +2777,13 @@ spell_free_all()
slang_free(lp);
}
if (temp_wordlist != NULL)
{
mch_remove(temp_wordlist);
vim_free(temp_wordlist);
temp_wordlist = NULL;
}
init_spell_chartab();
}
# endif
@@ -3967,6 +3971,7 @@ spell_read_wordfile(fname, spin)
char_u rline[MAXLINELEN];
char_u *line;
char_u *pc = NULL;
char_u *p;
int l;
int retval = OK;
int did_word = FALSE;
@@ -4035,13 +4040,9 @@ spell_read_wordfile(fname, spin)
line = rline;
}
flags = 0;
regionmask = spin->si_region;
if (*line == '/')
{
++line;
if (STRNCMP(line, "encoding=", 9) == 0)
{
if (spin->si_conv.vc_type != CONV_NONE)
@@ -4092,50 +4093,49 @@ spell_read_wordfile(fname, spin)
continue;
}
if (*line == '=')
smsg((char_u *)_("/ line ignored in %s line %d: %s"),
fname, lnum, line - 1);
continue;
}
flags = 0;
regionmask = spin->si_region;
/* Check for flags and region after a slash. */
p = vim_strchr(line, '/');
if (p != NULL)
{
/* keep-case word */
*p++ = NUL;
while (*p != NUL)
{
if (*p == '=') /* keep-case word */
flags |= WF_KEEPCAP;
++line;
}
if (*line == '!')
{
/* Bad, bad, wicked word. */
else if (*p == '!') /* Bad, bad, wicked word. */
flags |= WF_BANNED;
++line;
}
else if (*line == '?')
{
/* Rare word. */
else if (*p == '?') /* Rare word. */
flags |= WF_RARE;
++line;
}
if (VIM_ISDIGIT(*line))
else if (VIM_ISDIGIT(*p)) /* region number(s) */
{
/* region number(s) */
if ((flags & WF_REGION) == 0) /* first one */
regionmask = 0;
while (VIM_ISDIGIT(*line))
{
l = *line - '0';
flags |= WF_REGION;
l = *p - '0';
if (l > spin->si_region_count)
{
smsg((char_u *)_("Invalid region nr in %s line %d: %s"),
fname, lnum, line);
fname, lnum, p);
break;
}
regionmask |= 1 << (l - 1);
++line;
}
flags |= WF_REGION;
}
if (flags == 0)
else
{
smsg((char_u *)_("/ line ignored in %s line %d: %s"),
fname, lnum, line);
continue;
smsg((char_u *)_("Unrecognized flags in %s line %d: %s"),
fname, lnum, p);
break;
}
++p;
}
}
@@ -5179,23 +5179,38 @@ mkspell(fcount, fnames, ascii, overwrite, added_word)
ex_spell(eap)
exarg_T *eap;
{
spell_add_word(eap->arg, STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong);
spell_add_word(eap->arg, STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
eap->forceit);
}
/*
* Add "word[len]" to 'spellfile' as a good or bad word.
*/
void
spell_add_word(word, len, bad)
spell_add_word(word, len, bad, temp)
char_u *word;
int len;
int bad;
int temp; /* "zG" and "zW": use temp word list */
{
FILE *fd;
buf_T *buf;
int new_spf = FALSE;
struct stat st;
char_u *fname;
if (temp) /* use temp word list */
{
if (temp_wordlist == NULL)
{
temp_wordlist = vim_tempname('s');
if (temp_wordlist == NULL)
return;
}
fname = temp_wordlist;
}
else
{
/* If 'spellfile' isn't set figure out a good default value. */
if (*curbuf->b_p_spf == NUL)
{
@@ -5204,47 +5219,53 @@ spell_add_word(word, len, bad)
}
if (*curbuf->b_p_spf == NUL)
EMSG(_("E764: 'spellfile' is not set"));
else
{
EMSG(_("E764: 'spellfile' is not set"));
return;
}
/* Check that the user isn't editing the .add file somewhere. */
buf = buflist_findname_exp(curbuf->b_p_spf);
if (buf != NULL && buf->b_ml.ml_mfp == NULL)
buf = NULL;
if (buf != NULL && bufIsChanged(buf))
EMSG(_(e_bufloaded));
else
{
fd = mch_fopen((char *)curbuf->b_p_spf, "a");
EMSG(_(e_bufloaded));
return;
}
fname = curbuf->b_p_spf;
}
fd = mch_fopen((char *)fname, "a");
if (fd == NULL && new_spf)
{
/* We just initialized the 'spellfile' option and can't open
* the file. We may need to create the "spell" directory
* first. We already checked the runtime directory is
* writable in init_spellfile(). */
STRCPY(NameBuff, curbuf->b_p_spf);
/* We just initialized the 'spellfile' option and can't open the file.
* We may need to create the "spell" directory first. We already
* checked the runtime directory is writable in init_spellfile(). */
STRCPY(NameBuff, fname);
*gettail_sep(NameBuff) = NUL;
if (mch_stat((char *)NameBuff, &st) < 0)
{
/* The directory doesn't exist. Try creating it and
* opening the file again. */
/* The directory doesn't exist. Try creating it and opening the
* file again. */
vim_mkdir(NameBuff, 0755);
fd = mch_fopen((char *)curbuf->b_p_spf, "a");
fd = mch_fopen((char *)fname, "a");
}
}
if (fd == NULL)
EMSG2(_(e_notopen), curbuf->b_p_spf);
EMSG2(_(e_notopen), fname);
else
{
if (bad)
fprintf(fd, "/!%.*s\n", len, word);
fprintf(fd, "%.*s/!\n", len, word);
else
fprintf(fd, "%.*s\n", len, word);
fclose(fd);
/* Update the .add.spl file. */
mkspell(1, &curbuf->b_p_spf, FALSE, TRUE, TRUE);
mkspell(1, &fname, FALSE, TRUE, TRUE);
/* If the .add file is edited somewhere, reload it. */
if (buf != NULL)
@@ -5253,8 +5274,6 @@ spell_add_word(word, len, bad)
redraw_all_later(NOT_VALID);
}
}
}
}
/*
* Initialize 'spellfile' for the current buffer.
@@ -5475,9 +5494,8 @@ set_spell_chartab(fol, low, upp)
* Set the spell character tables from strings in the .spl file.
*/
static int
set_spell_charflags(flags, cnt, upp)
set_spell_charflags(flags, upp)
char_u *flags;
int cnt;
char_u *upp;
{
/* We build the new tables here first, so that we can compare with the
@@ -5489,7 +5507,7 @@ set_spell_charflags(flags, cnt, upp)
clear_spell_chartab(&new_st);
for (i = 0; i < cnt; ++i)
for (i = 0; flags[i] != NUL; ++i)
{
new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
@@ -9362,6 +9380,9 @@ ex_spelldump(eap)
int depth;
int n;
int flags;
char_u *region_names = NULL; /* region names being used */
int do_region = TRUE; /* dump region names and numbers */
char_u *p;
if (no_spell_checking())
return;
@@ -9371,6 +9392,34 @@ ex_spelldump(eap)
if (!bufempty() || !buf_valid(buf))
return;
/* 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)
{
p = lp->lp_slang->sl_regions;
if (p[0] != 0)
{
if (region_names == NULL) /* first language with regions */
region_names = p;
else if (STRCMP(region_names, p) != 0)
{
do_region = FALSE; /* region names are different */
break;
}
}
}
if (do_region && region_names != NULL)
{
vim_snprintf((char *)IObuff, IOSIZE, "/regions=%s", region_names);
ml_append(lnum++, IObuff, (colnr_T)0, FALSE);
}
else
do_region = FALSE;
/*
* Loop over all files loaded for the entries in 'spelllang'.
*/
for (lp = LANGP_ENTRY(buf->b_langp, 0); lp->lp_slang != NULL; ++lp)
{
slang = lp->lp_slang;
@@ -9420,11 +9469,14 @@ ex_spelldump(eap)
* Only use the word when the region matches. */
flags = (int)idxs[n];
if ((round == 2 || (flags & WF_KEEPCAP) == 0)
&& ((flags & WF_REGION) == 0
&& (do_region
|| (flags & WF_REGION) == 0
|| (((unsigned)flags >> 8)
& lp->lp_region) != 0))
{
word[depth] = NUL;
if (!do_region)
flags &= ~WF_REGION;
/* Dump the basic word if there is no prefix or
* when it's the first one. */
@@ -9470,7 +9522,8 @@ dump_word(word, round, flags, lnum)
int keepcap = FALSE;
char_u *p;
char_u cword[MAXWLEN];
char_u badword[MAXWLEN + 3];
char_u badword[MAXWLEN + 10];
int i;
if (round == 1 && (flags & WF_CAPMASK) != 0)
{
@@ -9485,18 +9538,21 @@ dump_word(word, round, flags, lnum)
keepcap = TRUE;
}
/* Bad word is preceded by "/!" and some other
* flags. */
if ((flags & (WF_BANNED | WF_RARE)) || keepcap)
/* Add flags and regions after a slash. */
if ((flags & (WF_BANNED | WF_RARE | WF_REGION)) || keepcap)
{
STRCPY(badword, "/");
STRCPY(badword, p);
STRCAT(badword, "/");
if (keepcap)
STRCAT(badword, "=");
if (flags & WF_BANNED)
STRCAT(badword, "!");
else if (flags & WF_RARE)
STRCAT(badword, "?");
STRCAT(badword, p);
if (flags & WF_REGION)
for (i = 0; i < 7; ++i)
if (flags & (0x100 << i))
sprintf((char *)badword + STRLEN(badword), "%d", i + 1);
p = badword;
}