mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
updated for version 7.0069
This commit is contained in:
parent
2c5bc17eb7
commit
2cf8b301df
@ -6071,9 +6071,14 @@ nv_brackets(cap)
|
|||||||
*/
|
*/
|
||||||
else if (cap->nchar == 's' || cap->nchar == 'S')
|
else if (cap->nchar == 's' || cap->nchar == 'S')
|
||||||
{
|
{
|
||||||
|
setpcmark();
|
||||||
|
for (n = 0; n < cap->count1; ++n)
|
||||||
if (spell_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD,
|
if (spell_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD,
|
||||||
cap->nchar == 's' ? TRUE : FALSE) == FAIL)
|
cap->nchar == 's' ? TRUE : FALSE) == FAIL)
|
||||||
|
{
|
||||||
clearopbeep(cap->oap);
|
clearopbeep(cap->oap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
406
src/spell.c
406
src/spell.c
@ -203,6 +203,7 @@ typedef struct langp_S
|
|||||||
#define BWF_ALLCAP 0x0400 /* all letters must be capital (not used
|
#define BWF_ALLCAP 0x0400 /* all letters must be capital (not used
|
||||||
for single-letter words) */
|
for single-letter words) */
|
||||||
#define BWF_KEEPCAP 0x0800 /* Keep case as-is */
|
#define BWF_KEEPCAP 0x0800 /* Keep case as-is */
|
||||||
|
#define BWF_ADDS_M 0x1000 /* there are more than 255 additions */
|
||||||
|
|
||||||
#define BWF_ADDHASH 0x8000 /* Internal: use hashtab for additions */
|
#define BWF_ADDHASH 0x8000 /* Internal: use hashtab for additions */
|
||||||
|
|
||||||
@ -212,6 +213,8 @@ typedef struct langp_S
|
|||||||
/* flags used for addition in the spell file */
|
/* flags used for addition in the spell file */
|
||||||
#define ADD_REGION 0x02 /* region byte follows */
|
#define ADD_REGION 0x02 /* region byte follows */
|
||||||
#define ADD_ONECAP 0x04 /* first letter must be capital */
|
#define ADD_ONECAP 0x04 /* first letter must be capital */
|
||||||
|
#define ADD_LEADLEN 0x10 /* there is a leadlen byte */
|
||||||
|
#define ADD_COPYLEN 0x20 /* there is a copylen byte */
|
||||||
#define ADD_ALLCAP 0x40 /* all letters must be capital (not used
|
#define ADD_ALLCAP 0x40 /* all letters must be capital (not used
|
||||||
for single-letter words) */
|
for single-letter words) */
|
||||||
#define ADD_KEEPCAP 0x80 /* fixed case */
|
#define ADD_KEEPCAP 0x80 /* fixed case */
|
||||||
@ -220,7 +223,7 @@ typedef struct langp_S
|
|||||||
* (Needed to keep ADD_ flags in one byte.) */
|
* (Needed to keep ADD_ flags in one byte.) */
|
||||||
#define ADD2BWF(x) (((x) & 0x0f) | (((x) & 0xf0) << 4))
|
#define ADD2BWF(x) (((x) & 0x0f) | (((x) & 0xf0) << 4))
|
||||||
|
|
||||||
#define VIMSPELLMAGIC "VIMspell02" /* string at start of Vim spell file */
|
#define VIMSPELLMAGIC "VIMspell03" /* string at start of Vim spell file */
|
||||||
#define VIMSPELLMAGICL 10
|
#define VIMSPELLMAGICL 10
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1164,13 +1167,17 @@ spell_move_to(dir, allwords)
|
|||||||
int dir; /* FORWARD or BACKWARD */
|
int dir; /* FORWARD or BACKWARD */
|
||||||
int allwords; /* TRUE for "[s" and "]s" */
|
int allwords; /* TRUE for "[s" and "]s" */
|
||||||
{
|
{
|
||||||
pos_T pos;
|
linenr_T lnum;
|
||||||
|
pos_T found_pos;
|
||||||
char_u *line;
|
char_u *line;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int wc;
|
int wc;
|
||||||
int nwc;
|
int nwc;
|
||||||
int attr = 0;
|
int attr = 0;
|
||||||
int len;
|
int len;
|
||||||
|
int has_syntax = syntax_present(curbuf);
|
||||||
|
int col;
|
||||||
|
int can_spell;
|
||||||
|
|
||||||
if (!curwin->w_p_spell || *curwin->w_buffer->b_p_spl == NUL)
|
if (!curwin->w_p_spell || *curwin->w_buffer->b_p_spl == NUL)
|
||||||
{
|
{
|
||||||
@ -1178,37 +1185,81 @@ spell_move_to(dir, allwords)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: moving backwards */
|
/*
|
||||||
|
* Start looking for bad word at the start of the line, because we can't
|
||||||
/* Start looking for bad word at the start of the line, because we can't
|
* start halfway a word, we don't know where it starts or ends.
|
||||||
* start halfway a word and know where it ends. */
|
*
|
||||||
pos = curwin->w_cursor;
|
* When searching backwards, we continue in the line to find the last
|
||||||
pos.col = 0;
|
* bad word (in the cursor line: before the cursor).
|
||||||
wc = FALSE;
|
*/
|
||||||
|
lnum = curwin->w_cursor.lnum;
|
||||||
|
found_pos.lnum = 0;
|
||||||
|
|
||||||
while (!got_int)
|
while (!got_int)
|
||||||
{
|
{
|
||||||
line = ml_get(pos.lnum);
|
line = ml_get(lnum);
|
||||||
p = line + pos.col;
|
p = line;
|
||||||
|
wc = FALSE;
|
||||||
|
|
||||||
while (*p != NUL)
|
while (*p != NUL)
|
||||||
{
|
{
|
||||||
nwc = spell_iswordc(p);
|
nwc = spell_iswordc(p);
|
||||||
if (!wc && nwc)
|
if (!wc && nwc)
|
||||||
{
|
{
|
||||||
|
/* When searching backward don't search after the cursor. */
|
||||||
|
if (dir == BACKWARD
|
||||||
|
&& lnum == curwin->w_cursor.lnum
|
||||||
|
&& (colnr_T)(p - line) >= curwin->w_cursor.col)
|
||||||
|
break;
|
||||||
|
|
||||||
/* start of word */
|
/* start of word */
|
||||||
/* TODO: check for bad word attr */
|
|
||||||
len = spell_check(curwin, line, p, &attr);
|
len = spell_check(curwin, line, p, &attr);
|
||||||
|
|
||||||
if (attr != 0)
|
if (attr != 0)
|
||||||
{
|
{
|
||||||
if (curwin->w_cursor.lnum < pos.lnum
|
/* We found a bad word. Check the attribute. */
|
||||||
|| (curwin->w_cursor.lnum == pos.lnum
|
/* TODO: check for syntax @Spell cluster. */
|
||||||
&& curwin->w_cursor.col < (colnr_T)(p - line)))
|
if (allwords || attr == highlight_attr[HLF_SPB])
|
||||||
{
|
{
|
||||||
curwin->w_cursor.lnum = pos.lnum;
|
/* When searching forward only accept a bad word after
|
||||||
curwin->w_cursor.col = p - line;
|
* the cursor. */
|
||||||
|
if (dir == BACKWARD
|
||||||
|
|| lnum > curwin->w_cursor.lnum
|
||||||
|
|| (lnum == curwin->w_cursor.lnum
|
||||||
|
&& (colnr_T)(p - line)
|
||||||
|
> curwin->w_cursor.col))
|
||||||
|
{
|
||||||
|
if (has_syntax)
|
||||||
|
{
|
||||||
|
col = p - line;
|
||||||
|
(void)syn_get_id(lnum, (colnr_T)col,
|
||||||
|
FALSE, &can_spell);
|
||||||
|
|
||||||
|
/* have to get the line again, a multi-line
|
||||||
|
* regexp may make it invalid */
|
||||||
|
line = ml_get(lnum);
|
||||||
|
p = line + col;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
can_spell = TRUE;
|
||||||
|
|
||||||
|
if (can_spell)
|
||||||
|
{
|
||||||
|
found_pos.lnum = lnum;
|
||||||
|
found_pos.col = p - line;
|
||||||
|
#ifdef FEAT_VIRTUALEDIT
|
||||||
|
found_pos.coladd = 0;
|
||||||
|
#endif
|
||||||
|
if (dir == FORWARD)
|
||||||
|
{
|
||||||
|
/* No need to search further. */
|
||||||
|
curwin->w_cursor = found_pos;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
attr = 0; /* bad word is before or at cursor */
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attr = 0;
|
||||||
}
|
}
|
||||||
p += len;
|
p += len;
|
||||||
if (*p == NUL)
|
if (*p == NUL)
|
||||||
@ -1222,11 +1273,24 @@ spell_move_to(dir, allwords)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Advance to next line. */
|
/* Advance to next line. */
|
||||||
if (pos.lnum == curbuf->b_ml.ml_line_count)
|
if (dir == BACKWARD)
|
||||||
|
{
|
||||||
|
if (found_pos.lnum != 0)
|
||||||
|
{
|
||||||
|
/* Use the last match in the line. */
|
||||||
|
curwin->w_cursor = found_pos;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
if (lnum == 1)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
++pos.lnum;
|
--lnum;
|
||||||
pos.col = 0;
|
}
|
||||||
wc = FALSE;
|
else
|
||||||
|
{
|
||||||
|
if (lnum == curbuf->b_ml.ml_line_count)
|
||||||
|
return FAIL;
|
||||||
|
++lnum;
|
||||||
|
}
|
||||||
|
|
||||||
line_breakcheck();
|
line_breakcheck();
|
||||||
}
|
}
|
||||||
@ -1773,7 +1837,10 @@ formerr:
|
|||||||
fw->fw_adds = NULL;
|
fw->fw_adds = NULL;
|
||||||
if (flags & BWF_ADDS)
|
if (flags & BWF_ADDS)
|
||||||
{
|
{
|
||||||
|
if (flags & BWF_ADDS_M)
|
||||||
adds = (getc(fd) << 8) + getc(fd); /* <addcnt> */
|
adds = (getc(fd) << 8) + getc(fd); /* <addcnt> */
|
||||||
|
else
|
||||||
|
adds = getc(fd); /* <addcnt> */
|
||||||
|
|
||||||
if (adds > 30)
|
if (adds > 30)
|
||||||
{
|
{
|
||||||
@ -1795,8 +1862,8 @@ formerr:
|
|||||||
|
|
||||||
while (--adds >= 0)
|
while (--adds >= 0)
|
||||||
{
|
{
|
||||||
/* <add>: <addflags> <addlen> [<leadlen> <addstring>]
|
/* <add>: <addflags> <addlen> [<leadlen>] [<copylen>]
|
||||||
* [<region>] */
|
* [<addstring>] [<region>] */
|
||||||
flags = getc(fd); /* <addflags> */
|
flags = getc(fd); /* <addflags> */
|
||||||
addlen = getc(fd); /* <addlen> */
|
addlen = getc(fd); /* <addlen> */
|
||||||
if (addlen == EOF)
|
if (addlen == EOF)
|
||||||
@ -1804,15 +1871,21 @@ formerr:
|
|||||||
if (addlen >= MAXWLEN)
|
if (addlen >= MAXWLEN)
|
||||||
goto formerr;
|
goto formerr;
|
||||||
|
|
||||||
|
if (flags & ADD_LEADLEN)
|
||||||
|
leadlen = getc(fd); /* <leadlen> */
|
||||||
|
else
|
||||||
|
leadlen = 0;
|
||||||
|
|
||||||
if (addlen > 0)
|
if (addlen > 0)
|
||||||
{
|
{
|
||||||
leadlen = getc(fd); /* <leadlen> */
|
if (flags & ADD_COPYLEN)
|
||||||
for (i = 0; i < addlen; ++i) /* <addstring> */
|
i = getc(fd); /* <copylen> */
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
for ( ; i < addlen; ++i) /* <addstring> */
|
||||||
cbuf[i] = getc(fd);
|
cbuf[i] = getc(fd);
|
||||||
cbuf[i] = NUL;
|
cbuf[i] = NUL;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
leadlen = 0;
|
|
||||||
|
|
||||||
if (flags & ADD_KEEPCAP)
|
if (flags & ADD_KEEPCAP)
|
||||||
{
|
{
|
||||||
@ -2292,6 +2365,20 @@ typedef struct affhash_S
|
|||||||
static affhash_T dumas;
|
static affhash_T dumas;
|
||||||
#define HI2AS(hi) ((affhash_T *)((hi)->hi_key - (dumas.as_word - (char_u *)&dumas)))
|
#define HI2AS(hi) ((affhash_T *)((hi)->hi_key - (dumas.as_word - (char_u *)&dumas)))
|
||||||
|
|
||||||
|
/* info for writing the spell file */
|
||||||
|
typedef struct winfo_S
|
||||||
|
{
|
||||||
|
FILE *wif_fd;
|
||||||
|
basicword_T *wif_prevbw; /* last written basic word */
|
||||||
|
int wif_regionmask; /* regions supported */
|
||||||
|
int wif_prefm; /* 1 or 2 bytes used for prefix NR */
|
||||||
|
int wif_suffm; /* 1 or 2 bytes used for suffix NR */
|
||||||
|
long wif_wcount; /* written word count */
|
||||||
|
long wif_acount; /* written addition count */
|
||||||
|
long wif_addmax; /* max number of additions on one word */
|
||||||
|
char_u *wif_addmaxw; /* word with max additions */
|
||||||
|
} winfo_T;
|
||||||
|
|
||||||
|
|
||||||
static afffile_T *spell_read_aff __ARGS((char_u *fname, vimconv_T *conv, int ascii));
|
static afffile_T *spell_read_aff __ARGS((char_u *fname, vimconv_T *conv, int ascii));
|
||||||
static void spell_free_aff __ARGS((afffile_T *aff));
|
static void spell_free_aff __ARGS((afffile_T *aff));
|
||||||
@ -2313,7 +2400,7 @@ static void put_bytes __ARGS((FILE *fd, long_u nr, int len));
|
|||||||
static void write_affix __ARGS((FILE *fd, affheader_T *ah));
|
static void write_affix __ARGS((FILE *fd, affheader_T *ah));
|
||||||
static void write_affixlist __ARGS((FILE *fd, garray_T *aff, int bytes));
|
static void write_affixlist __ARGS((FILE *fd, garray_T *aff, int bytes));
|
||||||
static void write_vim_spell __ARGS((char_u *fname, garray_T *prefga, garray_T *suffga, hashtab_T *newwords, int regcount, char_u *regchars));
|
static void write_vim_spell __ARGS((char_u *fname, garray_T *prefga, garray_T *suffga, hashtab_T *newwords, int regcount, char_u *regchars));
|
||||||
static void write_bword __ARGS((FILE *fd, basicword_T *bw, int lowcap, basicword_T **prevbw, int regionmask, int prefm, int suffm));
|
static void write_bword __ARGS((winfo_T *wif, basicword_T *bw, int lowcap));
|
||||||
static void free_wordtable __ARGS((hashtab_T *ht));
|
static void free_wordtable __ARGS((hashtab_T *ht));
|
||||||
static void free_basicword __ARGS((basicword_T *bw));
|
static void free_basicword __ARGS((basicword_T *bw));
|
||||||
static void free_affixentries __ARGS((affentry_T *first));
|
static void free_affixentries __ARGS((affentry_T *first));
|
||||||
@ -4019,7 +4106,7 @@ write_affixlist(fd, aff, bytes)
|
|||||||
*
|
*
|
||||||
* <HEADER>: <fileID> <regioncnt> <regionname> ...
|
* <HEADER>: <fileID> <regioncnt> <regionname> ...
|
||||||
*
|
*
|
||||||
* <fileID> 10 bytes "VIMspell02"
|
* <fileID> 10 bytes "VIMspell03"
|
||||||
* <regioncnt> 1 byte number of regions following (8 supported)
|
* <regioncnt> 1 byte number of regions following (8 supported)
|
||||||
* <regionname> 2 bytes Region name: ca, au, etc.
|
* <regionname> 2 bytes Region name: ca, au, etc.
|
||||||
* First <regionname> is region 1.
|
* First <regionname> is region 1.
|
||||||
@ -4085,6 +4172,8 @@ write_affixlist(fd, aff, bytes)
|
|||||||
* BWF_PREFIX
|
* BWF_PREFIX
|
||||||
* 0x04: all letters must be upper-case, BWF_ALLCAP
|
* 0x04: all letters must be upper-case, BWF_ALLCAP
|
||||||
* 0x08: case must match, BWF_KEEPCAP
|
* 0x08: case must match, BWF_KEEPCAP
|
||||||
|
* 0x10: has more than 255 additions, <addcnt> is two
|
||||||
|
* bytes, BWF_ADDS_M
|
||||||
* 0x10-0x80: unset
|
* 0x10-0x80: unset
|
||||||
* <caselen> 1 byte Length of <caseword>.
|
* <caselen> 1 byte Length of <caseword>.
|
||||||
* <caseword> N bytes Word with matching case.
|
* <caseword> N bytes Word with matching case.
|
||||||
@ -4094,20 +4183,23 @@ write_affixlist(fd, aff, bytes)
|
|||||||
* <region> 1 byte Bitmask for regions in which word is valid. When
|
* <region> 1 byte Bitmask for regions in which word is valid. When
|
||||||
* omitted it's valid in all regions.
|
* omitted it's valid in all regions.
|
||||||
* Lowest bit is for region 1.
|
* Lowest bit is for region 1.
|
||||||
* <addcnt> 2 bytes Number of <add> items following.
|
* <addcnt> 1 or 2 byte Number of <add> items following.
|
||||||
*
|
*
|
||||||
* <add>: <addflags> <addlen> [<leadlen> <addstring>] [<region>]
|
* <add>: <addflags> <addlen> [<leadlen>] [<copylen>] [<addstring>] [<region>]
|
||||||
*
|
*
|
||||||
* <addflags> 1 byte 0x01: unset
|
* <addflags> 1 byte 0x01: unset
|
||||||
* 0x02: has region byte, ADD_REGION
|
* 0x02: has region byte, ADD_REGION
|
||||||
* 0x04: first letter must be upper-case, ADD_ONECAP
|
* 0x04: first letter must be upper-case, ADD_ONECAP
|
||||||
* 0x08-0x20: unset
|
* 0x08: unset
|
||||||
|
* 0x10: has a <leadlen>, ADD_LEADLEN
|
||||||
|
* 0x20: has a <copylen>, ADD_COPYLEN
|
||||||
* 0x40: all letters must be upper-case, ADD_ALLCAP
|
* 0x40: all letters must be upper-case, ADD_ALLCAP
|
||||||
* 0x80: fixed case, <addstring> is the whole word
|
* 0x80: fixed case, <addstring> is the whole word
|
||||||
* with matching case, ADD_KEEPCAP.
|
* with matching case, ADD_KEEPCAP.
|
||||||
* <addlen> 1 byte Length of <addstring> in bytes.
|
* <addlen> 1 byte Length of <addstring> in bytes.
|
||||||
* <leadlen> 1 byte Number of bytes at start of <addstring> that must
|
* <leadlen> 1 byte Number of bytes at start of <addstring> that must
|
||||||
* come before the start of the basic word.
|
* come before the start of the basic word.
|
||||||
|
* <copylen> 1 byte Number of bytes copied from previous <addstring>.
|
||||||
* <addstring> N bytes Word characters, before/in/after the word.
|
* <addstring> N bytes Word characters, before/in/after the word.
|
||||||
*
|
*
|
||||||
* All text characters are in 'encoding': <affchop>, <affadd>, <string>,
|
* All text characters are in 'encoding': <affchop>, <affadd>, <string>,
|
||||||
@ -4128,48 +4220,48 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars)
|
|||||||
int regcount; /* number of regions */
|
int regcount; /* number of regions */
|
||||||
char_u *regchars; /* region names */
|
char_u *regchars; /* region names */
|
||||||
{
|
{
|
||||||
FILE *fd;
|
winfo_T wif;
|
||||||
garray_T *gap;
|
garray_T *gap;
|
||||||
hashitem_T *hi;
|
hashitem_T *hi;
|
||||||
char_u **wtab;
|
char_u **wtab;
|
||||||
int todo;
|
int todo;
|
||||||
int flags, aflags;
|
int flags, aflags;
|
||||||
basicword_T *bw, *bwf, *bw2 = NULL, *prevbw = NULL;
|
basicword_T *bw, *bwf, *bw2 = NULL;
|
||||||
int regionmask; /* mask for all relevant region bits */
|
|
||||||
int i;
|
int i;
|
||||||
int cnt;
|
int cnt;
|
||||||
affentry_T *ae;
|
affentry_T *ae;
|
||||||
int round;
|
int round;
|
||||||
int prefm, suffm;
|
|
||||||
garray_T bwga;
|
garray_T bwga;
|
||||||
|
|
||||||
fd = fopen((char *)fname, "w");
|
vim_memset(&wif, 0, sizeof(winfo_T));
|
||||||
if (fd == NULL)
|
|
||||||
|
wif.wif_fd = fopen((char *)fname, "w");
|
||||||
|
if (wif.wif_fd == NULL)
|
||||||
{
|
{
|
||||||
EMSG2(_(e_notopen), fname);
|
EMSG2(_(e_notopen), fname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd);
|
fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, wif.wif_fd);
|
||||||
|
|
||||||
/* write the region names if there is more than one */
|
/* write the region names if there is more than one */
|
||||||
if (regcount > 1)
|
if (regcount > 1)
|
||||||
{
|
{
|
||||||
putc(regcount, fd);
|
putc(regcount, wif.wif_fd);
|
||||||
fwrite(regchars, (size_t)(regcount * 2), (size_t)1, fd);
|
fwrite(regchars, (size_t)(regcount * 2), (size_t)1, wif.wif_fd);
|
||||||
regionmask = (1 << regcount) - 1;
|
wif.wif_regionmask = (1 << regcount) - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
putc(0, fd);
|
putc(0, wif.wif_fd);
|
||||||
regionmask = 0;
|
wif.wif_regionmask = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the prefix and suffix lists. */
|
/* Write the prefix and suffix lists. */
|
||||||
for (round = 1; round <= 2; ++round)
|
for (round = 1; round <= 2; ++round)
|
||||||
{
|
{
|
||||||
gap = round == 1 ? prefga : suffga;
|
gap = round == 1 ? prefga : suffga;
|
||||||
put_bytes(fd, (long_u)gap->ga_len, 2); /* <affcount> */
|
put_bytes(wif.wif_fd, (long_u)gap->ga_len, 2); /* <affcount> */
|
||||||
|
|
||||||
/* Count the total number of affix items. */
|
/* Count the total number of affix items. */
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
@ -4177,27 +4269,28 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars)
|
|||||||
for (ae = ((affheader_T *)gap->ga_data + i)->ah_first;
|
for (ae = ((affheader_T *)gap->ga_data + i)->ah_first;
|
||||||
ae != NULL; ae = ae->ae_next)
|
ae != NULL; ae = ae->ae_next)
|
||||||
++cnt;
|
++cnt;
|
||||||
put_bytes(fd, (long_u)cnt, 2); /* <afftotcnt> */
|
put_bytes(wif.wif_fd, (long_u)cnt, 2); /* <afftotcnt> */
|
||||||
|
|
||||||
for (i = 0; i < gap->ga_len; ++i)
|
for (i = 0; i < gap->ga_len; ++i)
|
||||||
write_affix(fd, (affheader_T *)gap->ga_data + i);
|
write_affix(wif.wif_fd, (affheader_T *)gap->ga_data + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of bytes used for affix NR depends on affix count. */
|
/* Number of bytes used for affix NR depends on affix count. */
|
||||||
prefm = (prefga->ga_len > 256) ? 2 : 1;
|
wif.wif_prefm = (prefga->ga_len > 256) ? 2 : 1;
|
||||||
suffm = (suffga->ga_len > 256) ? 2 : 1;
|
wif.wif_suffm = (suffga->ga_len > 256) ? 2 : 1;
|
||||||
|
|
||||||
/* Write the suggest info. TODO */
|
/* Write the suggest info. TODO */
|
||||||
put_bytes(fd, 0L, 4);
|
put_bytes(wif.wif_fd, 0L, 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the word list. <wordcount> <worditem> ...
|
* Write the word list. <wordcount> <worditem> ...
|
||||||
*/
|
*/
|
||||||
/* number of basic words in 4 bytes */
|
/* number of basic words in 4 bytes */
|
||||||
put_bytes(fd, newwords->ht_used, 4); /* <wordcount> */
|
put_bytes(wif.wif_fd, newwords->ht_used, 4); /* <wordcount> */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sort the word list, so that we can reuse as many bytes as possible.
|
* Sort the word list, so that we can copy as many bytes as possible from
|
||||||
|
* the previous word.
|
||||||
*/
|
*/
|
||||||
wtab = (char_u **)alloc((unsigned)(sizeof(char_u *) * newwords->ht_used));
|
wtab = (char_u **)alloc((unsigned)(sizeof(char_u *) * newwords->ht_used));
|
||||||
if (wtab != NULL)
|
if (wtab != NULL)
|
||||||
@ -4279,23 +4372,78 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars)
|
|||||||
* without VALID flag first (makes it easier to read the list back
|
* without VALID flag first (makes it easier to read the list back
|
||||||
* in). */
|
* in). */
|
||||||
if (bw->bw_flags & BWF_KEEPCAP)
|
if (bw->bw_flags & BWF_KEEPCAP)
|
||||||
write_bword(fd, bw, TRUE, &prevbw, regionmask, prefm, suffm);
|
write_bword(&wif, bw, TRUE);
|
||||||
write_bword(fd, bw, FALSE, &prevbw, regionmask, prefm, suffm);
|
write_bword(&wif, bw, FALSE);
|
||||||
|
|
||||||
/* Write other basic words, with different caps. */
|
/* Write other basic words, with different caps. */
|
||||||
for (i = 0; i < bwga.ga_len; ++i)
|
for (i = 0; i < bwga.ga_len; ++i)
|
||||||
{
|
{
|
||||||
bw2 = ((basicword_T **)bwga.ga_data)[i];
|
bw2 = ((basicword_T **)bwga.ga_data)[i];
|
||||||
if (bw2 != bw)
|
if (bw2 != bw)
|
||||||
write_bword(fd, bw2, FALSE, &prevbw, regionmask,
|
write_bword(&wif, bw2, FALSE);
|
||||||
prefm, suffm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ga_clear(&bwga);
|
ga_clear(&bwga);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fd);
|
fclose(wif.wif_fd);
|
||||||
|
|
||||||
|
/* Print a few statistics. */
|
||||||
|
if (wif.wif_addmaxw == NULL)
|
||||||
|
wif.wif_addmaxw = (char_u *)"";
|
||||||
|
smsg((char_u *)_("Maximum number of adds on a word: %ld (%s)"),
|
||||||
|
wif.wif_addmax, wif.wif_addmaxw);
|
||||||
|
smsg((char_u *)_("Average number of adds on a word: %f"),
|
||||||
|
(float)wif.wif_acount / (float)wif.wif_wcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare two basic words for their <addstring>.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
_RTLENTRYF
|
||||||
|
#endif
|
||||||
|
bw_compare __ARGS((const void *s1, const void *s2));
|
||||||
|
|
||||||
|
static int
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
_RTLENTRYF
|
||||||
|
#endif
|
||||||
|
bw_compare(s1, s2)
|
||||||
|
const void *s1;
|
||||||
|
const void *s2;
|
||||||
|
{
|
||||||
|
basicword_T *bw1 = *(basicword_T **)s1;
|
||||||
|
basicword_T *bw2 = *(basicword_T **)s2;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/* compare the leadstrings */
|
||||||
|
if (bw1->bw_leadstring == NULL)
|
||||||
|
{
|
||||||
|
if (bw2->bw_leadstring != NULL)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (bw2->bw_leadstring == NULL)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
i = STRCMP(bw1->bw_leadstring, bw2->bw_leadstring);
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
/* leadstrings are identical, compare the addstrings */
|
||||||
|
if (bw1->bw_addstring == NULL)
|
||||||
|
{
|
||||||
|
if (bw2->bw_addstring != NULL)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (bw2->bw_addstring == NULL)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
i = STRCMP(bw1->bw_addstring, bw2->bw_addstring);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4309,34 +4457,36 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars)
|
|||||||
* [<addcnt> <add> ...]
|
* [<addcnt> <add> ...]
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm)
|
write_bword(wif, bwf, lowcap)
|
||||||
FILE *fd;
|
winfo_T *wif; /* info for writing */
|
||||||
basicword_T *bwf;
|
basicword_T *bwf;
|
||||||
int lowcap; /* write KEEPKAP word as not-valid */
|
int lowcap; /* write KEEPKAP word as not-valid */
|
||||||
basicword_T **prevbw; /* last written basic word */
|
|
||||||
int regionmask; /* mask that includes all possible regions */
|
|
||||||
int prefm;
|
|
||||||
int suffm;
|
|
||||||
{
|
{
|
||||||
|
FILE *fd = wif->wif_fd;
|
||||||
int flags;
|
int flags;
|
||||||
int aflags;
|
int aflags;
|
||||||
int len;
|
int len;
|
||||||
int leadlen, addlen;
|
int leadlen, addlen;
|
||||||
|
int copylen;
|
||||||
int clen;
|
int clen;
|
||||||
int adds = 0;
|
int adds = 0;
|
||||||
int i;
|
int i;
|
||||||
|
int idx;
|
||||||
basicword_T *bw, *bw2;
|
basicword_T *bw, *bw2;
|
||||||
|
basicword_T **wtab;
|
||||||
|
int count;
|
||||||
|
int l;
|
||||||
|
|
||||||
/* Check how many bytes can be copied from the previous word. */
|
/* Check how many bytes can be copied from the previous word. */
|
||||||
len = STRLEN(bwf->bw_word);
|
len = STRLEN(bwf->bw_word);
|
||||||
if (*prevbw == NULL)
|
if (wif->wif_prevbw == NULL)
|
||||||
clen = 0;
|
clen = 0;
|
||||||
else
|
else
|
||||||
for (clen = 0; clen < len
|
for (clen = 0; clen < len
|
||||||
&& (*prevbw)->bw_word[clen] == bwf->bw_word[clen]; ++clen)
|
&& wif->wif_prevbw->bw_word[clen] == bwf->bw_word[clen]; ++clen)
|
||||||
;
|
;
|
||||||
putc(clen, fd); /* <nr> */
|
putc(clen, fd); /* <nr> */
|
||||||
*prevbw = bwf;
|
wif->wif_prevbw = bwf;
|
||||||
/* <string> */
|
/* <string> */
|
||||||
if (len > clen)
|
if (len > clen)
|
||||||
fwrite(bwf->bw_word + clen, (size_t)(len - clen), (size_t)1, fd);
|
fwrite(bwf->bw_word + clen, (size_t)(len - clen), (size_t)1, fd);
|
||||||
@ -4360,7 +4510,8 @@ write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm)
|
|||||||
|
|
||||||
/* Flags: add the region byte if the word isn't valid in all
|
/* Flags: add the region byte if the word isn't valid in all
|
||||||
* regions. */
|
* regions. */
|
||||||
if (regionmask != 0 && (bw->bw_region & regionmask) != regionmask)
|
if (wif->wif_regionmask != 0 && (bw->bw_region & wif->wif_regionmask)
|
||||||
|
!= wif->wif_regionmask)
|
||||||
flags |= BWF_REGION;
|
flags |= BWF_REGION;
|
||||||
}
|
}
|
||||||
/* Add the prefix/suffix list if there are prefixes/suffixes. */
|
/* Add the prefix/suffix list if there are prefixes/suffixes. */
|
||||||
@ -4371,7 +4522,11 @@ write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm)
|
|||||||
|
|
||||||
/* Flags: may have additions. */
|
/* Flags: may have additions. */
|
||||||
if (adds > 0)
|
if (adds > 0)
|
||||||
|
{
|
||||||
flags |= BWF_ADDS;
|
flags |= BWF_ADDS;
|
||||||
|
if (adds >= 256)
|
||||||
|
flags |= BWF_ADDS_M;
|
||||||
|
}
|
||||||
|
|
||||||
/* The dummy word before a KEEPCAP word doesn't have any flags, they are
|
/* The dummy word before a KEEPCAP word doesn't have any flags, they are
|
||||||
* in the actual word that follows. */
|
* in the actual word that follows. */
|
||||||
@ -4403,56 +4558,133 @@ write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm)
|
|||||||
|
|
||||||
/* write prefix and suffix lists: <affixcnt> <affixNR> ... */
|
/* write prefix and suffix lists: <affixcnt> <affixNR> ... */
|
||||||
if (flags & BWF_PREFIX)
|
if (flags & BWF_PREFIX)
|
||||||
write_affixlist(fd, &bw->bw_prefix, prefm);
|
write_affixlist(fd, &bw->bw_prefix, wif->wif_prefm);
|
||||||
if (flags & BWF_SUFFIX)
|
if (flags & BWF_SUFFIX)
|
||||||
write_affixlist(fd, &bw->bw_suffix, suffm);
|
write_affixlist(fd, &bw->bw_suffix, wif->wif_suffm);
|
||||||
|
|
||||||
if (flags & BWF_REGION)
|
if (flags & BWF_REGION)
|
||||||
putc(bw->bw_region, fd); /* <region> */
|
putc(bw->bw_region, fd); /* <region> */
|
||||||
|
|
||||||
|
++wif->wif_wcount;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Additions.
|
* Additions.
|
||||||
*/
|
*/
|
||||||
if (adds > 0)
|
if (adds > 0)
|
||||||
{
|
{
|
||||||
put_bytes(fd, (long_u)adds, 2); /* <addcnt> */
|
if (adds >= 256)
|
||||||
|
put_bytes(fd, (long_u)adds, 2); /* 2 byte <addcnt> */
|
||||||
|
else
|
||||||
|
putc(adds, fd); /* 1 byte <addcnt> */
|
||||||
|
|
||||||
|
/* statistics */
|
||||||
|
wif->wif_acount += adds;
|
||||||
|
if (wif->wif_addmax < adds)
|
||||||
|
{
|
||||||
|
wif->wif_addmax = adds;
|
||||||
|
wif->wif_addmaxw = bw->bw_word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sort the list of additions, so that we can copy as many bytes as
|
||||||
|
* possible from the previous addstring.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Make a table with pointers to each basic word that has additions. */
|
||||||
|
wtab = (basicword_T **)alloc((unsigned)(sizeof(basicword_T *) * adds));
|
||||||
|
if (wtab == NULL)
|
||||||
|
return;
|
||||||
|
count = 0;
|
||||||
for (bw = bwf; bw != NULL; bw = bw->bw_cnext)
|
for (bw = bwf; bw != NULL; bw = bw->bw_cnext)
|
||||||
if (bw->bw_leadstring != NULL || bw->bw_addstring != NULL)
|
if (bw->bw_leadstring != NULL || bw->bw_addstring != NULL)
|
||||||
|
wtab[count++] = bw;
|
||||||
|
|
||||||
|
/* Sort. */
|
||||||
|
qsort((void *)wtab, (size_t)count, sizeof(basicword_T *), bw_compare);
|
||||||
|
|
||||||
|
/* Now write each basic word to the spell file. Copy bytes from the
|
||||||
|
* previous leadstring/addstring if possible. */
|
||||||
|
bw2 = NULL;
|
||||||
|
for (idx = 0; idx < count; ++idx)
|
||||||
{
|
{
|
||||||
/* <add>: <addflags> <addlen> [<leadlen> <addstring>]
|
bw = wtab[idx];
|
||||||
* [<region>] */
|
|
||||||
|
/* <add>: <addflags> <addlen> [<leadlen>] [<copylen>]
|
||||||
|
* [<addstring>] [<region>] */
|
||||||
|
copylen = 0;
|
||||||
|
if (bw->bw_leadstring == NULL)
|
||||||
|
leadlen = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leadlen = STRLEN(bw->bw_leadstring);
|
||||||
|
if (bw2 != NULL && bw2->bw_leadstring != NULL)
|
||||||
|
for ( ; copylen < leadlen; ++copylen)
|
||||||
|
if (bw->bw_leadstring[copylen]
|
||||||
|
!= bw2->bw_leadstring[copylen])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bw->bw_addstring == NULL)
|
||||||
|
addlen = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addlen = STRLEN(bw->bw_addstring);
|
||||||
|
if (bw2 != NULL && copylen == leadlen
|
||||||
|
&& bw2->bw_addstring != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < addlen; ++i)
|
||||||
|
if (bw->bw_addstring[i] != bw2->bw_addstring[i])
|
||||||
|
break;
|
||||||
|
copylen += i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
aflags = 0;
|
aflags = 0;
|
||||||
|
/* Only copy bytes when it's more than one, the length itself
|
||||||
|
* takes an extra byte. */
|
||||||
|
if (copylen > 1)
|
||||||
|
aflags |= ADD_COPYLEN;
|
||||||
|
else
|
||||||
|
copylen = 0;
|
||||||
|
|
||||||
if (bw->bw_flags & BWF_ONECAP)
|
if (bw->bw_flags & BWF_ONECAP)
|
||||||
aflags |= ADD_ONECAP;
|
aflags |= ADD_ONECAP;
|
||||||
if (bw->bw_flags & BWF_ALLCAP)
|
if (bw->bw_flags & BWF_ALLCAP)
|
||||||
aflags |= ADD_ALLCAP;
|
aflags |= ADD_ALLCAP;
|
||||||
if (bw->bw_flags & BWF_KEEPCAP)
|
if (bw->bw_flags & BWF_KEEPCAP)
|
||||||
aflags |= ADD_KEEPCAP;
|
aflags |= ADD_KEEPCAP;
|
||||||
if (regionmask != 0
|
if (wif->wif_regionmask != 0 && (bw->bw_region
|
||||||
&& (bw->bw_region & regionmask) != regionmask)
|
& wif->wif_regionmask) != wif->wif_regionmask)
|
||||||
aflags |= ADD_REGION;
|
aflags |= ADD_REGION;
|
||||||
|
if (leadlen > 0)
|
||||||
|
aflags |= ADD_LEADLEN;
|
||||||
putc(aflags, fd); /* <addflags> */
|
putc(aflags, fd); /* <addflags> */
|
||||||
|
|
||||||
if (bw->bw_leadstring == NULL)
|
|
||||||
leadlen = 0;
|
|
||||||
else
|
|
||||||
leadlen = STRLEN(bw->bw_leadstring);
|
|
||||||
if (bw->bw_addstring == NULL)
|
|
||||||
addlen = 0;
|
|
||||||
else
|
|
||||||
addlen = STRLEN(bw->bw_addstring);
|
|
||||||
putc(leadlen + addlen, fd); /* <addlen> */
|
putc(leadlen + addlen, fd); /* <addlen> */
|
||||||
|
if (aflags & ADD_LEADLEN)
|
||||||
putc(leadlen, fd); /* <leadlen> */
|
putc(leadlen, fd); /* <leadlen> */
|
||||||
|
if (aflags & ADD_COPYLEN)
|
||||||
|
putc(copylen, fd); /* <copylen> */
|
||||||
|
|
||||||
/* <addstring> */
|
/* <addstring> */
|
||||||
if (bw->bw_leadstring != NULL)
|
if (leadlen > copylen && bw->bw_leadstring != NULL)
|
||||||
fwrite(bw->bw_leadstring, (size_t)leadlen, (size_t)1, fd);
|
fwrite(bw->bw_leadstring + copylen,
|
||||||
if (bw->bw_addstring != NULL)
|
(size_t)(leadlen - copylen), (size_t)1, fd);
|
||||||
fwrite(bw->bw_addstring, (size_t)addlen, (size_t)1, fd);
|
if (leadlen + addlen > copylen && bw->bw_addstring != NULL)
|
||||||
|
{
|
||||||
|
if (copylen >= leadlen)
|
||||||
|
l = copylen - leadlen;
|
||||||
|
else
|
||||||
|
l = 0;
|
||||||
|
fwrite(bw->bw_addstring + l,
|
||||||
|
(size_t)(addlen - l), (size_t)1, fd);
|
||||||
|
}
|
||||||
|
|
||||||
if (aflags & ADD_REGION)
|
if (aflags & ADD_REGION)
|
||||||
putc(bw->bw_region, fd); /* <region> */
|
putc(bw->bw_region, fd); /* <region> */
|
||||||
|
|
||||||
|
bw2 = bw;
|
||||||
}
|
}
|
||||||
|
vim_free(wtab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user