mirror of
https://github.com/neovim/neovim.git
synced 2025-11-25 11:40:40 +00:00
vim-patch:8.1.0810: too many #ifdefs
Problem: Too many #ifdefs.
Solution: Graduate FEAT_MBYTE, part 4.
264b74fa54
This commit is contained in:
@@ -563,9 +563,7 @@ void AppendToRedobuffLit(const char_u *str, int len)
|
|||||||
|
|
||||||
// Handle a special or multibyte character.
|
// Handle a special or multibyte character.
|
||||||
// Composing chars separately are handled separately.
|
// Composing chars separately are handled separately.
|
||||||
const int c = (has_mbyte
|
const int c = mb_cptr2char_adv((const char_u **)&s);
|
||||||
? mb_cptr2char_adv((const char_u **)&s)
|
|
||||||
: (uint8_t)(*s++));
|
|
||||||
if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^'))) {
|
if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^'))) {
|
||||||
add_char_buff(&redobuff, Ctrl_V);
|
add_char_buff(&redobuff, Ctrl_V);
|
||||||
}
|
}
|
||||||
@@ -684,15 +682,16 @@ static int read_redo(bool init, bool old_redo)
|
|||||||
if ((c = *p) == NUL) {
|
if ((c = *p) == NUL) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
/* Reverse the conversion done by add_char_buff() */
|
// Reverse the conversion done by add_char_buff() */
|
||||||
/* For a multi-byte character get all the bytes and return the
|
// For a multi-byte character get all the bytes and return the
|
||||||
* converted character. */
|
// converted character.
|
||||||
if (has_mbyte && (c != K_SPECIAL || p[1] == KS_SPECIAL))
|
if (c != K_SPECIAL || p[1] == KS_SPECIAL) {
|
||||||
n = MB_BYTE2LEN_CHECK(c);
|
n = MB_BYTE2LEN_CHECK(c);
|
||||||
else
|
} else {
|
||||||
n = 1;
|
n = 1;
|
||||||
for (i = 0;; ++i) {
|
}
|
||||||
if (c == K_SPECIAL) { /* special key or escaped K_SPECIAL */
|
for (i = 0;; i++) {
|
||||||
|
if (c == K_SPECIAL) { // special key or escaped K_SPECIAL
|
||||||
c = TO_SPECIAL(p[1], p[2]);
|
c = TO_SPECIAL(p[1], p[2]);
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
@@ -2161,14 +2160,11 @@ static int vgetorpeek(bool advance)
|
|||||||
col = vcol = curwin->w_wcol = 0;
|
col = vcol = curwin->w_wcol = 0;
|
||||||
ptr = get_cursor_line_ptr();
|
ptr = get_cursor_line_ptr();
|
||||||
while (col < curwin->w_cursor.col) {
|
while (col < curwin->w_cursor.col) {
|
||||||
if (!ascii_iswhite(ptr[col]))
|
if (!ascii_iswhite(ptr[col])) {
|
||||||
curwin->w_wcol = vcol;
|
curwin->w_wcol = vcol;
|
||||||
vcol += lbr_chartabsize(ptr, ptr + col,
|
}
|
||||||
(colnr_T)vcol);
|
vcol += lbr_chartabsize(ptr, ptr + col, (colnr_T)vcol);
|
||||||
if (has_mbyte)
|
col += utfc_ptr2len(ptr + col);
|
||||||
col += (*mb_ptr2len)(ptr + col);
|
|
||||||
else
|
|
||||||
++col;
|
|
||||||
}
|
}
|
||||||
curwin->w_wrow = curwin->w_cline_row
|
curwin->w_wrow = curwin->w_cline_row
|
||||||
+ curwin->w_wcol / curwin->w_width_inner;
|
+ curwin->w_wcol / curwin->w_width_inner;
|
||||||
@@ -2813,33 +2809,23 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
|
|||||||
// Otherwise we won't be able to find the start of it in a
|
// Otherwise we won't be able to find the start of it in a
|
||||||
// vi-compatible way.
|
// vi-compatible way.
|
||||||
//
|
//
|
||||||
if (has_mbyte) {
|
int same = -1;
|
||||||
int first, last;
|
|
||||||
int same = -1;
|
|
||||||
|
|
||||||
first = vim_iswordp(lhs);
|
const int first = vim_iswordp(lhs);
|
||||||
last = first;
|
int last = first;
|
||||||
p = lhs + (*mb_ptr2len)(lhs);
|
p = lhs + utfc_ptr2len(lhs);
|
||||||
n = 1;
|
n = 1;
|
||||||
while (p < lhs + len) {
|
while (p < lhs + len) {
|
||||||
n++; // nr of (multi-byte) chars
|
n++; // nr of (multi-byte) chars
|
||||||
last = vim_iswordp(p); // type of last char
|
last = vim_iswordp(p); // type of last char
|
||||||
if (same == -1 && last != first) {
|
if (same == -1 && last != first) {
|
||||||
same = n - 1; // count of same char type
|
same = n - 1; // count of same char type
|
||||||
}
|
|
||||||
p += (*mb_ptr2len)(p);
|
|
||||||
}
|
}
|
||||||
if (last && n > 2 && same >= 0 && same < n - 1) {
|
p += (*mb_ptr2len)(p);
|
||||||
retval = 1;
|
}
|
||||||
goto theend;
|
if (last && n > 2 && same >= 0 && same < n - 1) {
|
||||||
}
|
retval = 1;
|
||||||
} else if (vim_iswordc(lhs[len - 1])) { // ends in keyword char
|
goto theend;
|
||||||
for (n = 0; n < len - 2; n++) {
|
|
||||||
if (vim_iswordc(lhs[n]) != vim_iswordc(lhs[len - 2])) {
|
|
||||||
retval = 1;
|
|
||||||
goto theend;
|
|
||||||
}
|
|
||||||
} // for
|
|
||||||
}
|
}
|
||||||
// An abbreviation cannot contain white space.
|
// An abbreviation cannot contain white space.
|
||||||
for (n = 0; n < len; n++) {
|
for (n = 0; n < len; n++) {
|
||||||
@@ -3700,25 +3686,23 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
|
|||||||
return count == 0 ? FAIL : OK;
|
return count == 0 ? FAIL : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check for an abbreviation.
|
||||||
* Check for an abbreviation.
|
// Cursor is at ptr[col].
|
||||||
* Cursor is at ptr[col].
|
// When inserting, mincol is where insert started.
|
||||||
* When inserting, mincol is where insert started.
|
// For the command line, mincol is what is to be skipped over.
|
||||||
* For the command line, mincol is what is to be skipped over.
|
// "c" is the character typed before check_abbr was called. It may have
|
||||||
* "c" is the character typed before check_abbr was called. It may have
|
// ABBR_OFF added to avoid prepending a CTRL-V to it.
|
||||||
* ABBR_OFF added to avoid prepending a CTRL-V to it.
|
//
|
||||||
*
|
// Historic vi practice: The last character of an abbreviation must be an id
|
||||||
* Historic vi practice: The last character of an abbreviation must be an id
|
// character ([a-zA-Z0-9_]). The characters in front of it must be all id
|
||||||
* character ([a-zA-Z0-9_]). The characters in front of it must be all id
|
// characters or all non-id characters. This allows for abbr. "#i" to
|
||||||
* characters or all non-id characters. This allows for abbr. "#i" to
|
// "#include".
|
||||||
* "#include".
|
//
|
||||||
*
|
// Vim addition: Allow for abbreviations that end in a non-keyword character.
|
||||||
* Vim addition: Allow for abbreviations that end in a non-keyword character.
|
// Then there must be white space before the abbr.
|
||||||
* Then there must be white space before the abbr.
|
//
|
||||||
*
|
// Return true if there is an abbreviation, false if not.
|
||||||
* return TRUE if there is an abbreviation, FALSE if not
|
bool check_abbr(int c, char_u *ptr, int col, int mincol)
|
||||||
*/
|
|
||||||
int check_abbr(int c, char_u *ptr, int col, int mincol)
|
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int scol; /* starting column of the abbr. */
|
int scol; /* starting column of the abbr. */
|
||||||
@@ -3727,36 +3711,36 @@ int check_abbr(int c, char_u *ptr, int col, int mincol)
|
|||||||
char_u tb[MB_MAXBYTES + 4];
|
char_u tb[MB_MAXBYTES + 4];
|
||||||
mapblock_T *mp;
|
mapblock_T *mp;
|
||||||
mapblock_T *mp2;
|
mapblock_T *mp2;
|
||||||
int clen = 0; /* length in characters */
|
int clen = 0; // length in characters
|
||||||
int is_id = TRUE;
|
bool is_id = true;
|
||||||
int vim_abbr;
|
|
||||||
|
|
||||||
if (typebuf.tb_no_abbr_cnt) /* abbrev. are not recursive */
|
if (typebuf.tb_no_abbr_cnt) { // abbrev. are not recursive
|
||||||
return FALSE;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* no remapping implies no abbreviation, except for CTRL-] */
|
// no remapping implies no abbreviation, except for CTRL-]
|
||||||
if ((KeyNoremap & (RM_NONE|RM_SCRIPT)) != 0 && c != Ctrl_RSB)
|
if ((KeyNoremap & (RM_NONE|RM_SCRIPT)) != 0 && c != Ctrl_RSB) {
|
||||||
return FALSE;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
// Check for word before the cursor: If it ends in a keyword char all
|
||||||
* Check for word before the cursor: If it ends in a keyword char all
|
// chars before it must be keyword chars or non-keyword chars, but not
|
||||||
* chars before it must be keyword chars or non-keyword chars, but not
|
// white space. If it ends in a non-keyword char we accept any characters
|
||||||
* white space. If it ends in a non-keyword char we accept any characters
|
// before it except white space.
|
||||||
* before it except white space.
|
if (col == 0) { // cannot be an abbr.
|
||||||
*/
|
return false;
|
||||||
if (col == 0) /* cannot be an abbr. */
|
}
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (has_mbyte) {
|
{
|
||||||
char_u *p;
|
bool vim_abbr;
|
||||||
|
char_u *p = mb_prevptr(ptr, ptr + col);
|
||||||
p = mb_prevptr(ptr, ptr + col);
|
if (!vim_iswordp(p)) {
|
||||||
if (!vim_iswordp(p))
|
vim_abbr = true; // Vim added abbr.
|
||||||
vim_abbr = TRUE; /* Vim added abbr. */
|
} else {
|
||||||
else {
|
vim_abbr = false; // vi compatible abbr.
|
||||||
vim_abbr = FALSE; /* vi compatible abbr. */
|
if (p > ptr) {
|
||||||
if (p > ptr)
|
|
||||||
is_id = vim_iswordp(mb_prevptr(ptr, p));
|
is_id = vim_iswordp(mb_prevptr(ptr, p));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
clen = 1;
|
clen = 1;
|
||||||
while (p > ptr + mincol) {
|
while (p > ptr + mincol) {
|
||||||
@@ -3768,17 +3752,6 @@ int check_abbr(int c, char_u *ptr, int col, int mincol)
|
|||||||
++clen;
|
++clen;
|
||||||
}
|
}
|
||||||
scol = (int)(p - ptr);
|
scol = (int)(p - ptr);
|
||||||
} else {
|
|
||||||
if (!vim_iswordc(ptr[col - 1]))
|
|
||||||
vim_abbr = TRUE; /* Vim added abbr. */
|
|
||||||
else {
|
|
||||||
vim_abbr = FALSE; /* vi compatible abbr. */
|
|
||||||
if (col > 1)
|
|
||||||
is_id = vim_iswordc(ptr[col - 2]);
|
|
||||||
}
|
|
||||||
for (scol = col - 1; scol > 0 && !ascii_isspace(ptr[scol - 1])
|
|
||||||
&& (vim_abbr || is_id == vim_iswordc(ptr[scol - 1])); --scol)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scol < mincol)
|
if (scol < mincol)
|
||||||
@@ -3866,14 +3839,14 @@ int check_abbr(int c, char_u *ptr, int col, int mincol)
|
|||||||
|
|
||||||
tb[0] = Ctrl_H;
|
tb[0] = Ctrl_H;
|
||||||
tb[1] = NUL;
|
tb[1] = NUL;
|
||||||
if (has_mbyte)
|
len = clen; // Delete characters instead of bytes
|
||||||
len = clen; /* Delete characters instead of bytes */
|
while (len-- > 0) { // delete the from string
|
||||||
while (len-- > 0) /* delete the from string */
|
(void)ins_typebuf(tb, 1, 0, true, mp->m_silent);
|
||||||
(void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
|
}
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -218,14 +218,11 @@ char_u *reverse_text(char_u *s) FUNC_ATTR_NONNULL_RET
|
|||||||
size_t len = STRLEN(s);
|
size_t len = STRLEN(s);
|
||||||
char_u *rev = xmalloc(len + 1);
|
char_u *rev = xmalloc(len + 1);
|
||||||
size_t rev_i = len;
|
size_t rev_i = len;
|
||||||
for (size_t s_i = 0; s_i < len; ++s_i) {
|
for (size_t s_i = 0; s_i < len; s_i++) {
|
||||||
if (has_mbyte) {
|
const int mb_len = utfc_ptr2len(s + s_i);
|
||||||
int mb_len = (*mb_ptr2len)(s + s_i);
|
rev_i -= mb_len;
|
||||||
rev_i -= mb_len;
|
memmove(rev + rev_i, s + s_i, mb_len);
|
||||||
memmove(rev + rev_i, s + s_i, mb_len);
|
s_i += mb_len - 1;
|
||||||
s_i += mb_len - 1;
|
|
||||||
} else
|
|
||||||
rev[--rev_i] = s[s_i];
|
|
||||||
}
|
}
|
||||||
rev[len] = NUL;
|
rev[len] = NUL;
|
||||||
|
|
||||||
@@ -594,8 +591,8 @@ int searchit(
|
|||||||
// is zero.
|
// is zero.
|
||||||
if (pos->col == MAXCOL) {
|
if (pos->col == MAXCOL) {
|
||||||
start_char_len = 0;
|
start_char_len = 0;
|
||||||
} else if (has_mbyte
|
} else if (pos->lnum >= 1
|
||||||
&& pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
|
&& pos->lnum <= buf->b_ml.ml_line_count
|
||||||
&& pos->col < MAXCOL - 2) {
|
&& pos->col < MAXCOL - 2) {
|
||||||
// Watch out for the "col" being MAXCOL - 2, used in a closed fold.
|
// Watch out for the "col" being MAXCOL - 2, used in a closed fold.
|
||||||
ptr = ml_get_buf(buf, pos->lnum, false);
|
ptr = ml_get_buf(buf, pos->lnum, false);
|
||||||
@@ -1553,34 +1550,26 @@ int searchc(cmdarg_T *cap, int t_cmd)
|
|||||||
len = (int)STRLEN(p);
|
len = (int)STRLEN(p);
|
||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
if (has_mbyte) {
|
for (;; ) {
|
||||||
for (;; ) {
|
if (dir > 0) {
|
||||||
if (dir > 0) {
|
col += utfc_ptr2len(p + col);
|
||||||
col += (*mb_ptr2len)(p + col);
|
if (col >= len) {
|
||||||
if (col >= len)
|
|
||||||
return FAIL;
|
|
||||||
} else {
|
|
||||||
if (col == 0)
|
|
||||||
return FAIL;
|
|
||||||
col -= utf_head_off(p, p + col - 1) + 1;
|
|
||||||
}
|
|
||||||
if (lastc_bytelen == 1) {
|
|
||||||
if (p[col] == c && stop) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (STRNCMP(p + col, lastc_bytes, lastc_bytelen) == 0 && stop) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stop = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (;; ) {
|
|
||||||
if ((col += dir) < 0 || col >= len)
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
if (p[col] == c && stop)
|
}
|
||||||
break;
|
} else {
|
||||||
stop = TRUE;
|
if (col == 0) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
col -= utf_head_off(p, p + col - 1) + 1;
|
||||||
}
|
}
|
||||||
|
if (lastc_bytelen == 1) {
|
||||||
|
if (p[col] == c && stop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (STRNCMP(p + col, lastc_bytes, lastc_bytelen) == 0 && stop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stop = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1964,10 +1953,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|
|||||||
if (lisp) /* find comment pos in new line */
|
if (lisp) /* find comment pos in new line */
|
||||||
comment_col = check_linecomment(linep);
|
comment_col = check_linecomment(linep);
|
||||||
} else {
|
} else {
|
||||||
if (has_mbyte)
|
pos.col += utfc_ptr2len(linep + pos.col);
|
||||||
pos.col += (*mb_ptr2len)(linep + pos.col);
|
|
||||||
else
|
|
||||||
++pos.col;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
573
src/nvim/spell.c
573
src/nvim/spell.c
@@ -513,10 +513,7 @@ size_t spell_check(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_mbyte) {
|
return (size_t)(utfc_ptr2len(ptr));
|
||||||
return (size_t)(*mb_ptr2len)(ptr);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
} else if (mi.mi_end == ptr) {
|
} else if (mi.mi_end == ptr) {
|
||||||
// Always include at least one character. Required for when there
|
// Always include at least one character. Required for when there
|
||||||
// is a mixup in "midword".
|
// is a mixup in "midword".
|
||||||
@@ -722,7 +719,7 @@ static void find_word(matchinf_T *mip, int mode)
|
|||||||
// has been found we try compound flags.
|
// has been found we try compound flags.
|
||||||
bool prefix_found = false;
|
bool prefix_found = false;
|
||||||
|
|
||||||
if (mode != FIND_KEEPWORD && has_mbyte) {
|
if (mode != FIND_KEEPWORD) {
|
||||||
// Compute byte length in original word, length may change
|
// Compute byte length in original word, length may change
|
||||||
// when folding case. This can be slow, take a shortcut when the
|
// when folding case. This can be slow, take a shortcut when the
|
||||||
// case-folded word is equal to the keep-case word.
|
// case-folded word is equal to the keep-case word.
|
||||||
@@ -796,11 +793,11 @@ static void find_word(matchinf_T *mip, int mode)
|
|||||||
continue;
|
continue;
|
||||||
// For multi-byte chars check character length against
|
// For multi-byte chars check character length against
|
||||||
// COMPOUNDMIN.
|
// COMPOUNDMIN.
|
||||||
if (has_mbyte
|
if (slang->sl_compminlen > 0
|
||||||
&& slang->sl_compminlen > 0
|
|
||||||
&& mb_charlen_len(mip->mi_word + mip->mi_compoff,
|
&& mb_charlen_len(mip->mi_word + mip->mi_compoff,
|
||||||
wlen - mip->mi_compoff) < slang->sl_compminlen)
|
wlen - mip->mi_compoff) < slang->sl_compminlen) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Limit the number of compound words to COMPOUNDWORDMAX if no
|
// Limit the number of compound words to COMPOUNDWORDMAX if no
|
||||||
// maximum for syllables is specified.
|
// maximum for syllables is specified.
|
||||||
@@ -833,8 +830,7 @@ static void find_word(matchinf_T *mip, int mode)
|
|||||||
|
|
||||||
// Need to check the caps type of the appended compound
|
// Need to check the caps type of the appended compound
|
||||||
// word.
|
// word.
|
||||||
if (has_mbyte && STRNCMP(ptr, mip->mi_word,
|
if (STRNCMP(ptr, mip->mi_word, mip->mi_compoff) != 0) {
|
||||||
mip->mi_compoff) != 0) {
|
|
||||||
// case folding may have changed the length
|
// case folding may have changed the length
|
||||||
p = mip->mi_word;
|
p = mip->mi_word;
|
||||||
for (char_u *s = ptr; s < ptr + mip->mi_compoff; MB_PTR_ADV(s)) {
|
for (char_u *s = ptr; s < ptr + mip->mi_compoff; MB_PTR_ADV(s)) {
|
||||||
@@ -907,7 +903,7 @@ static void find_word(matchinf_T *mip, int mode)
|
|||||||
|
|
||||||
// Find following word in case-folded tree.
|
// Find following word in case-folded tree.
|
||||||
mip->mi_compoff = endlen[endidxcnt];
|
mip->mi_compoff = endlen[endidxcnt];
|
||||||
if (has_mbyte && mode == FIND_KEEPWORD) {
|
if (mode == FIND_KEEPWORD) {
|
||||||
// Compute byte length in case-folded word from "wlen":
|
// Compute byte length in case-folded word from "wlen":
|
||||||
// byte length in keep-case word. Length may change when
|
// byte length in keep-case word. Length may change when
|
||||||
// folding case. This can be slow, take a shortcut when
|
// folding case. This can be slow, take a shortcut when
|
||||||
@@ -1260,12 +1256,9 @@ static void find_prefix(matchinf_T *mip, int mode)
|
|||||||
// Skip over the previously found word(s).
|
// Skip over the previously found word(s).
|
||||||
mip->mi_prefixlen += mip->mi_compoff;
|
mip->mi_prefixlen += mip->mi_compoff;
|
||||||
|
|
||||||
if (has_mbyte) {
|
// Case-folded length may differ from original length.
|
||||||
// Case-folded length may differ from original length.
|
mip->mi_cprefixlen = nofold_len(mip->mi_fword, mip->mi_prefixlen,
|
||||||
mip->mi_cprefixlen = nofold_len(mip->mi_fword,
|
mip->mi_word);
|
||||||
mip->mi_prefixlen, mip->mi_word);
|
|
||||||
} else
|
|
||||||
mip->mi_cprefixlen = mip->mi_prefixlen;
|
|
||||||
find_word(mip, FIND_PREFIX);
|
find_word(mip, FIND_PREFIX);
|
||||||
|
|
||||||
|
|
||||||
@@ -2272,35 +2265,30 @@ static void clear_midword(win_T *wp)
|
|||||||
// Use the "sl_midword" field of language "lp" for buffer "buf".
|
// Use the "sl_midword" field of language "lp" for buffer "buf".
|
||||||
// They add up to any currently used midword characters.
|
// They add up to any currently used midword characters.
|
||||||
static void use_midword(slang_T *lp, win_T *wp)
|
static void use_midword(slang_T *lp, win_T *wp)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
char_u *p;
|
if (lp->sl_midword == NULL) { // there aren't any
|
||||||
|
|
||||||
if (lp->sl_midword == NULL) // there aren't any
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (p = lp->sl_midword; *p != NUL; )
|
for (char_u *p = lp->sl_midword; *p != NUL; ) {
|
||||||
if (has_mbyte) {
|
const int c = utf_ptr2char(p);
|
||||||
int c, l, n;
|
const int l = utfc_ptr2len(p);
|
||||||
char_u *bp;
|
if (c < 256 && l <= 2) {
|
||||||
|
wp->w_s->b_spell_ismw[c] = true;
|
||||||
c = utf_ptr2char(p);
|
} else if (wp->w_s->b_spell_ismw_mb == NULL) {
|
||||||
l = (*mb_ptr2len)(p);
|
// First multi-byte char in "b_spell_ismw_mb".
|
||||||
if (c < 256 && l <= 2)
|
wp->w_s->b_spell_ismw_mb = vim_strnsave(p, l);
|
||||||
wp->w_s->b_spell_ismw[c] = true;
|
} else {
|
||||||
else if (wp->w_s->b_spell_ismw_mb == NULL)
|
// Append multi-byte chars to "b_spell_ismw_mb".
|
||||||
// First multi-byte char in "b_spell_ismw_mb".
|
const int n = (int)STRLEN(wp->w_s->b_spell_ismw_mb);
|
||||||
wp->w_s->b_spell_ismw_mb = vim_strnsave(p, l);
|
char_u *bp = vim_strnsave(wp->w_s->b_spell_ismw_mb, n + l);
|
||||||
else {
|
xfree(wp->w_s->b_spell_ismw_mb);
|
||||||
// Append multi-byte chars to "b_spell_ismw_mb".
|
wp->w_s->b_spell_ismw_mb = bp;
|
||||||
n = (int)STRLEN(wp->w_s->b_spell_ismw_mb);
|
STRLCPY(bp + n, p, l + 1);
|
||||||
bp = vim_strnsave(wp->w_s->b_spell_ismw_mb, n + l);
|
}
|
||||||
xfree(wp->w_s->b_spell_ismw_mb);
|
p += l;
|
||||||
wp->w_s->b_spell_ismw_mb = bp;
|
}
|
||||||
STRLCPY(bp + n, p, l + 1);
|
|
||||||
}
|
|
||||||
p += l;
|
|
||||||
} else
|
|
||||||
wp->w_s->b_spell_ismw[*p++] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the region "region[2]" in "rp" (points to "sl_regions").
|
// Find the region "region[2]" in "rp" (points to "sl_regions").
|
||||||
@@ -2333,7 +2321,6 @@ int captype(char_u *word, char_u *end)
|
|||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int c;
|
|
||||||
int firstcap;
|
int firstcap;
|
||||||
bool allcap;
|
bool allcap;
|
||||||
bool past_second = false; // past second word char
|
bool past_second = false; // past second word char
|
||||||
@@ -2344,11 +2331,7 @@ int captype(char_u *word, char_u *end)
|
|||||||
return 0; // only non-word characters, illegal word
|
return 0; // only non-word characters, illegal word
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_mbyte) {
|
int c = mb_ptr2char_adv((const char_u **)&p);
|
||||||
c = mb_ptr2char_adv((const char_u **)&p);
|
|
||||||
} else {
|
|
||||||
c = *p++;
|
|
||||||
}
|
|
||||||
firstcap = allcap = SPELL_ISUPPER(c);
|
firstcap = allcap = SPELL_ISUPPER(c);
|
||||||
|
|
||||||
// Need to check all letters to find a word with mixed upper/lower.
|
// Need to check all letters to find a word with mixed upper/lower.
|
||||||
@@ -2673,34 +2656,23 @@ static bool spell_iswordp_w(const int *p, const win_T *wp)
|
|||||||
// Returns FAIL when something wrong.
|
// Returns FAIL when something wrong.
|
||||||
int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
|
int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if (len >= buflen) {
|
if (len >= buflen) {
|
||||||
buf[0] = NUL;
|
buf[0] = NUL;
|
||||||
return FAIL; // result will not fit
|
return FAIL; // result will not fit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_mbyte) {
|
int outi = 0;
|
||||||
int outi = 0;
|
|
||||||
char_u *p;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
// Fold one character at a time.
|
// Fold one character at a time.
|
||||||
for (p = str; p < str + len; ) {
|
for (char_u *p = str; p < str + len; ) {
|
||||||
if (outi + MB_MAXBYTES > buflen) {
|
if (outi + MB_MAXBYTES > buflen) {
|
||||||
buf[outi] = NUL;
|
buf[outi] = NUL;
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
|
||||||
c = mb_cptr2char_adv((const char_u **)&p);
|
|
||||||
outi += utf_char2bytes(SPELL_TOFOLD(c), buf + outi);
|
|
||||||
}
|
}
|
||||||
buf[outi] = NUL;
|
const int c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
} else {
|
outi += utf_char2bytes(SPELL_TOFOLD(c), buf + outi);
|
||||||
// Be quick for non-multibyte encodings.
|
|
||||||
for (i = 0; i < len; ++i)
|
|
||||||
buf[i] = spelltab.st_fold[str[i]];
|
|
||||||
buf[i] = NUL;
|
|
||||||
}
|
}
|
||||||
|
buf[outi] = NUL;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -3428,22 +3400,14 @@ static void spell_find_cleanup(suginfo_T *su)
|
|||||||
/// @param[in] upper True to upper case, otherwise lower case
|
/// @param[in] upper True to upper case, otherwise lower case
|
||||||
void onecap_copy(char_u *word, char_u *wcopy, bool upper)
|
void onecap_copy(char_u *word, char_u *wcopy, bool upper)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p = word;
|
||||||
int c;
|
int c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
int l;
|
|
||||||
|
|
||||||
p = word;
|
|
||||||
if (has_mbyte) {
|
|
||||||
c = mb_cptr2char_adv((const char_u **)&p);
|
|
||||||
} else {
|
|
||||||
c = *p++;
|
|
||||||
}
|
|
||||||
if (upper) {
|
if (upper) {
|
||||||
c = SPELL_TOUPPER(c);
|
c = SPELL_TOUPPER(c);
|
||||||
} else {
|
} else {
|
||||||
c = SPELL_TOFOLD(c);
|
c = SPELL_TOFOLD(c);
|
||||||
}
|
}
|
||||||
l = utf_char2bytes(c, wcopy);
|
int l = utf_char2bytes(c, wcopy);
|
||||||
STRLCPY(wcopy + l, p, MAXWLEN - l);
|
STRLCPY(wcopy + l, p, MAXWLEN - l);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3451,17 +3415,9 @@ void onecap_copy(char_u *word, char_u *wcopy, bool upper)
|
|||||||
// "wcopy[MAXWLEN]". The result is NUL terminated.
|
// "wcopy[MAXWLEN]". The result is NUL terminated.
|
||||||
static void allcap_copy(char_u *word, char_u *wcopy)
|
static void allcap_copy(char_u *word, char_u *wcopy)
|
||||||
{
|
{
|
||||||
char_u *s;
|
char_u *d = wcopy;
|
||||||
char_u *d;
|
for (char_u *s = word; *s != NUL; ) {
|
||||||
int c;
|
int c = mb_cptr2char_adv((const char_u **)&s);
|
||||||
|
|
||||||
d = wcopy;
|
|
||||||
for (s = word; *s != NUL; ) {
|
|
||||||
if (has_mbyte) {
|
|
||||||
c = mb_cptr2char_adv((const char_u **)&s);
|
|
||||||
} else {
|
|
||||||
c = *s++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == 0xdf) {
|
if (c == 0xdf) {
|
||||||
c = 'S';
|
c = 'S';
|
||||||
@@ -3730,10 +3686,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX) {
|
if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX) {
|
||||||
// Set su->su_badflags to the caps type at this position.
|
// Set su->su_badflags to the caps type at this position.
|
||||||
// Use the caps type until here for the prefix itself.
|
// Use the caps type until here for the prefix itself.
|
||||||
if (has_mbyte)
|
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
|
||||||
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
|
|
||||||
else
|
|
||||||
n = sp->ts_fidx;
|
|
||||||
flags = badword_captype(su->su_badptr, su->su_badptr + n);
|
flags = badword_captype(su->su_badptr, su->su_badptr + n);
|
||||||
su->su_badflags = badword_captype(su->su_badptr + n,
|
su->su_badflags = badword_captype(su->su_badptr + n,
|
||||||
su->su_badptr + su->su_badlen);
|
su->su_badptr + su->su_badlen);
|
||||||
@@ -3851,15 +3804,16 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
// flag).
|
// flag).
|
||||||
if (((unsigned)flags >> 24) == 0
|
if (((unsigned)flags >> 24) == 0
|
||||||
|| sp->ts_twordlen - sp->ts_splitoff
|
|| sp->ts_twordlen - sp->ts_splitoff
|
||||||
< slang->sl_compminlen)
|
< slang->sl_compminlen) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// For multi-byte chars check character length against
|
// For multi-byte chars check character length against
|
||||||
// COMPOUNDMIN.
|
// COMPOUNDMIN.
|
||||||
if (has_mbyte
|
if (slang->sl_compminlen > 0
|
||||||
&& slang->sl_compminlen > 0
|
|
||||||
&& mb_charlen(tword + sp->ts_splitoff)
|
&& mb_charlen(tword + sp->ts_splitoff)
|
||||||
< slang->sl_compminlen)
|
< slang->sl_compminlen) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
compflags[sp->ts_complen] = ((unsigned)flags >> 24);
|
compflags[sp->ts_complen] = ((unsigned)flags >> 24);
|
||||||
compflags[sp->ts_complen + 1] = NUL;
|
compflags[sp->ts_complen + 1] = NUL;
|
||||||
@@ -4014,7 +3968,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
// Try word split and/or compounding.
|
// Try word split and/or compounding.
|
||||||
if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends)
|
if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends)
|
||||||
// Don't split in the middle of a character
|
// Don't split in the middle of a character
|
||||||
&& (!has_mbyte || sp->ts_tcharlen == 0)
|
&& (sp->ts_tcharlen == 0)
|
||||||
) {
|
) {
|
||||||
bool try_compound;
|
bool try_compound;
|
||||||
int try_split;
|
int try_split;
|
||||||
@@ -4046,8 +4000,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
&& ((unsigned)flags >> 24) != 0
|
&& ((unsigned)flags >> 24) != 0
|
||||||
&& sp->ts_twordlen - sp->ts_splitoff
|
&& sp->ts_twordlen - sp->ts_splitoff
|
||||||
>= slang->sl_compminlen
|
>= slang->sl_compminlen
|
||||||
&& (!has_mbyte
|
&& (slang->sl_compminlen == 0
|
||||||
|| slang->sl_compminlen == 0
|
|
||||||
|| mb_charlen(tword + sp->ts_splitoff)
|
|| mb_charlen(tword + sp->ts_splitoff)
|
||||||
>= slang->sl_compminlen)
|
>= slang->sl_compminlen)
|
||||||
&& (slang->sl_compsylmax < MAXWLEN
|
&& (slang->sl_compsylmax < MAXWLEN
|
||||||
@@ -4166,10 +4119,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
|
|
||||||
// set su->su_badflags to the caps type at this
|
// set su->su_badflags to the caps type at this
|
||||||
// position
|
// position
|
||||||
if (has_mbyte)
|
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
|
||||||
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
|
|
||||||
else
|
|
||||||
n = sp->ts_fidx;
|
|
||||||
su->su_badflags = badword_captype(su->su_badptr + n,
|
su->su_badflags = badword_captype(su->su_badptr + n,
|
||||||
su->su_badptr + su->su_badlen);
|
su->su_badptr + su->su_badlen);
|
||||||
|
|
||||||
@@ -4266,84 +4216,74 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
++sp->ts_fidx;
|
++sp->ts_fidx;
|
||||||
tword[sp->ts_twordlen++] = c;
|
tword[sp->ts_twordlen++] = c;
|
||||||
sp->ts_arridx = idxs[arridx];
|
sp->ts_arridx = idxs[arridx];
|
||||||
if (newscore == SCORE_SUBST)
|
if (newscore == SCORE_SUBST) {
|
||||||
sp->ts_isdiff = DIFF_YES;
|
sp->ts_isdiff = DIFF_YES;
|
||||||
if (has_mbyte) {
|
}
|
||||||
// Multi-byte characters are a bit complicated to
|
// Multi-byte characters are a bit complicated to
|
||||||
// handle: They differ when any of the bytes differ
|
// handle: They differ when any of the bytes differ
|
||||||
// and then their length may also differ.
|
// and then their length may also differ.
|
||||||
if (sp->ts_tcharlen == 0) {
|
if (sp->ts_tcharlen == 0) {
|
||||||
// First byte.
|
// First byte.
|
||||||
sp->ts_tcharidx = 0;
|
sp->ts_tcharidx = 0;
|
||||||
sp->ts_tcharlen = MB_BYTE2LEN(c);
|
sp->ts_tcharlen = MB_BYTE2LEN(c);
|
||||||
sp->ts_fcharstart = sp->ts_fidx - 1;
|
sp->ts_fcharstart = sp->ts_fidx - 1;
|
||||||
sp->ts_isdiff = (newscore != 0)
|
sp->ts_isdiff = (newscore != 0)
|
||||||
? DIFF_YES : DIFF_NONE;
|
? DIFF_YES : DIFF_NONE;
|
||||||
} else if (sp->ts_isdiff == DIFF_INSERT)
|
} else if (sp->ts_isdiff == DIFF_INSERT) {
|
||||||
// When inserting trail bytes don't advance in the
|
// When inserting trail bytes don't advance in the
|
||||||
// bad word.
|
// bad word.
|
||||||
--sp->ts_fidx;
|
sp->ts_fidx--;
|
||||||
if (++sp->ts_tcharidx == sp->ts_tcharlen) {
|
}
|
||||||
// Last byte of character.
|
if (++sp->ts_tcharidx == sp->ts_tcharlen) {
|
||||||
if (sp->ts_isdiff == DIFF_YES) {
|
// Last byte of character.
|
||||||
// Correct ts_fidx for the byte length of the
|
if (sp->ts_isdiff == DIFF_YES) {
|
||||||
// character (we didn't check that before).
|
// Correct ts_fidx for the byte length of the
|
||||||
sp->ts_fidx = sp->ts_fcharstart
|
// character (we didn't check that before).
|
||||||
+ utfc_ptr2len(fword + sp->ts_fcharstart);
|
sp->ts_fidx = sp->ts_fcharstart
|
||||||
|
+ utfc_ptr2len(fword + sp->ts_fcharstart);
|
||||||
|
|
||||||
// For changing a composing character adjust
|
// For changing a composing character adjust
|
||||||
// the score from SCORE_SUBST to
|
// the score from SCORE_SUBST to
|
||||||
// SCORE_SUBCOMP.
|
// SCORE_SUBCOMP.
|
||||||
if (utf_iscomposing(utf_ptr2char(tword + sp->ts_twordlen
|
if (utf_iscomposing(utf_ptr2char(tword + sp->ts_twordlen
|
||||||
- sp->ts_tcharlen))
|
- sp->ts_tcharlen))
|
||||||
&& utf_iscomposing(utf_ptr2char(fword
|
&& utf_iscomposing(utf_ptr2char(fword
|
||||||
+ sp->ts_fcharstart))) {
|
+ sp->ts_fcharstart))) {
|
||||||
sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP;
|
sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP;
|
||||||
} else if (
|
} else if (
|
||||||
!soundfold
|
!soundfold
|
||||||
&& slang->sl_has_map
|
&& slang->sl_has_map
|
||||||
&& similar_chars(
|
&& similar_chars(
|
||||||
slang,
|
slang,
|
||||||
utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
|
utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
|
||||||
utf_ptr2char(fword + sp->ts_fcharstart))) {
|
utf_ptr2char(fword + sp->ts_fcharstart))) {
|
||||||
// For a similar character adjust score from
|
// For a similar character adjust score from
|
||||||
// SCORE_SUBST to SCORE_SIMILAR.
|
// SCORE_SUBST to SCORE_SIMILAR.
|
||||||
sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
|
sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
|
||||||
}
|
}
|
||||||
} else if (sp->ts_isdiff == DIFF_INSERT
|
} else if (sp->ts_isdiff == DIFF_INSERT
|
||||||
&& sp->ts_twordlen > sp->ts_tcharlen) {
|
&& sp->ts_twordlen > sp->ts_tcharlen) {
|
||||||
p = tword + sp->ts_twordlen - sp->ts_tcharlen;
|
p = tword + sp->ts_twordlen - sp->ts_tcharlen;
|
||||||
c = utf_ptr2char(p);
|
c = utf_ptr2char(p);
|
||||||
if (utf_iscomposing(c)) {
|
if (utf_iscomposing(c)) {
|
||||||
// Inserting a composing char doesn't
|
// Inserting a composing char doesn't
|
||||||
// count that much.
|
// count that much.
|
||||||
sp->ts_score -= SCORE_INS - SCORE_INSCOMP;
|
sp->ts_score -= SCORE_INS - SCORE_INSCOMP;
|
||||||
} else {
|
} else {
|
||||||
// If the previous character was the same,
|
// If the previous character was the same,
|
||||||
// thus doubling a character, give a bonus
|
// thus doubling a character, give a bonus
|
||||||
// to the score. Also for the soundfold
|
// to the score. Also for the soundfold
|
||||||
// tree (might seem illogical but does
|
// tree (might seem illogical but does
|
||||||
// give better scores).
|
// give better scores).
|
||||||
MB_PTR_BACK(tword, p);
|
MB_PTR_BACK(tword, p);
|
||||||
if (c == utf_ptr2char(p)) {
|
if (c == utf_ptr2char(p)) {
|
||||||
sp->ts_score -= SCORE_INS - SCORE_INSDUP;
|
sp->ts_score -= SCORE_INS - SCORE_INSDUP;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starting a new char, reset the length.
|
|
||||||
sp->ts_tcharlen = 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// If we found a similar char adjust the score.
|
// Starting a new char, reset the length.
|
||||||
// We do this after calling go_deeper() because
|
sp->ts_tcharlen = 0;
|
||||||
// it's slow.
|
|
||||||
if (newscore != 0
|
|
||||||
&& !soundfold
|
|
||||||
&& slang->sl_has_map
|
|
||||||
&& similar_chars(slang,
|
|
||||||
c, fword[sp->ts_fidx - 1]))
|
|
||||||
sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4352,7 +4292,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
case STATE_DEL:
|
case STATE_DEL:
|
||||||
// When past the first byte of a multi-byte char don't try
|
// When past the first byte of a multi-byte char don't try
|
||||||
// delete/insert/swap a character.
|
// delete/insert/swap a character.
|
||||||
if (has_mbyte && sp->ts_tcharlen > 0) {
|
if (sp->ts_tcharlen > 0) {
|
||||||
PROF_STORE(sp->ts_state)
|
PROF_STORE(sp->ts_state)
|
||||||
sp->ts_state = STATE_FINAL;
|
sp->ts_state = STATE_FINAL;
|
||||||
break;
|
break;
|
||||||
@@ -4461,18 +4401,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
|||||||
sp = &stack[depth];
|
sp = &stack[depth];
|
||||||
tword[sp->ts_twordlen++] = c;
|
tword[sp->ts_twordlen++] = c;
|
||||||
sp->ts_arridx = idxs[n];
|
sp->ts_arridx = idxs[n];
|
||||||
if (has_mbyte) {
|
fl = MB_BYTE2LEN(c);
|
||||||
fl = MB_BYTE2LEN(c);
|
if (fl > 1) {
|
||||||
if (fl > 1) {
|
// There are following bytes for the same character.
|
||||||
// There are following bytes for the same character.
|
// We must find all bytes before trying
|
||||||
// We must find all bytes before trying
|
// delete/insert/swap/etc.
|
||||||
// delete/insert/swap/etc.
|
sp->ts_tcharlen = fl;
|
||||||
sp->ts_tcharlen = fl;
|
sp->ts_tcharidx = 1;
|
||||||
sp->ts_tcharidx = 1;
|
sp->ts_isdiff = DIFF_INSERT;
|
||||||
sp->ts_isdiff = DIFF_INSERT;
|
}
|
||||||
}
|
|
||||||
} else
|
|
||||||
fl = 1;
|
|
||||||
if (fl == 1) {
|
if (fl == 1) {
|
||||||
// If the previous character was the same, thus doubling a
|
// If the previous character was the same, thus doubling a
|
||||||
// character, give a bonus to the score. Also for
|
// character, give a bonus to the score. Also for
|
||||||
@@ -4914,12 +4851,8 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
|
|||||||
} else {
|
} else {
|
||||||
// round[depth] == 1: Try using the folded-case character.
|
// round[depth] == 1: Try using the folded-case character.
|
||||||
// round[depth] == 2: Try using the upper-case character.
|
// round[depth] == 2: Try using the upper-case character.
|
||||||
if (has_mbyte) {
|
flen = MB_CPTR2LEN(fword + fwordidx[depth]);
|
||||||
flen = MB_CPTR2LEN(fword + fwordidx[depth]);
|
ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
|
||||||
ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
|
|
||||||
} else {
|
|
||||||
ulen = flen = 1;
|
|
||||||
}
|
|
||||||
if (round[depth] == 1) {
|
if (round[depth] == 1) {
|
||||||
p = fword + fwordidx[depth];
|
p = fword + fwordidx[depth];
|
||||||
l = flen;
|
l = flen;
|
||||||
@@ -5872,57 +5805,43 @@ void spell_soundfold(slang_T *slang, char_u *inword, bool folded, char_u *res)
|
|||||||
// SOFOTO lines.
|
// SOFOTO lines.
|
||||||
static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
|
static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
|
||||||
{
|
{
|
||||||
char_u *s;
|
|
||||||
int ri = 0;
|
int ri = 0;
|
||||||
int c;
|
|
||||||
|
|
||||||
if (has_mbyte) {
|
int prevc = 0;
|
||||||
int prevc = 0;
|
|
||||||
int *ip;
|
|
||||||
|
|
||||||
// The sl_sal_first[] table contains the translation for chars up to
|
// The sl_sal_first[] table contains the translation for chars up to
|
||||||
// 255, sl_sal the rest.
|
// 255, sl_sal the rest.
|
||||||
for (s = inword; *s != NUL; ) {
|
for (char_u *s = inword; *s != NUL; ) {
|
||||||
c = mb_cptr2char_adv((const char_u **)&s);
|
int c = mb_cptr2char_adv((const char_u **)&s);
|
||||||
if (utf_class(c) == 0) {
|
if (utf_class(c) == 0) {
|
||||||
c = ' ';
|
c = ' ';
|
||||||
} else if (c < 256) {
|
} else if (c < 256) {
|
||||||
c = slang->sl_sal_first[c];
|
c = slang->sl_sal_first[c];
|
||||||
|
} else {
|
||||||
|
int *ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
|
||||||
|
if (ip == NULL) { // empty list, can't match
|
||||||
|
c = NUL;
|
||||||
} else {
|
} else {
|
||||||
ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
|
for (;; ) { // find "c" in the list
|
||||||
if (ip == NULL) // empty list, can't match
|
if (*ip == 0) { // not found
|
||||||
c = NUL;
|
c = NUL;
|
||||||
else
|
break;
|
||||||
for (;; ) { // find "c" in the list
|
|
||||||
if (*ip == 0) { // not found
|
|
||||||
c = NUL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*ip == c) { // match!
|
|
||||||
c = ip[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ip += 2;
|
|
||||||
}
|
}
|
||||||
}
|
if (*ip == c) { // match!
|
||||||
|
c = ip[1];
|
||||||
if (c != NUL && c != prevc) {
|
break;
|
||||||
ri += utf_char2bytes(c, res + ri);
|
}
|
||||||
if (ri + MB_MAXBYTES > MAXWLEN) {
|
ip += 2;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
prevc = c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// The sl_sal_first[] table contains the translation.
|
if (c != NUL && c != prevc) {
|
||||||
for (s = inword; (c = *s) != NUL; ++s) {
|
ri += utf_char2bytes(c, res + ri);
|
||||||
if (ascii_iswhite(c))
|
if (ri + MB_MAXBYTES > MAXWLEN) {
|
||||||
c = ' ';
|
break;
|
||||||
else
|
}
|
||||||
c = slang->sl_sal_first[c];
|
prevc = c;
|
||||||
if (c != NUL && (ri == 0 || res[ri - 1] != c))
|
|
||||||
res[ri++] = c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6425,12 +6344,11 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
|
|||||||
int pbc, pgc;
|
int pbc, pgc;
|
||||||
int wbadword[MAXWLEN];
|
int wbadword[MAXWLEN];
|
||||||
int wgoodword[MAXWLEN];
|
int wgoodword[MAXWLEN];
|
||||||
const bool l_has_mbyte = has_mbyte;
|
|
||||||
|
|
||||||
// Lengths with NUL.
|
// Lengths with NUL.
|
||||||
int badlen;
|
int badlen;
|
||||||
int goodlen;
|
int goodlen;
|
||||||
if (l_has_mbyte) {
|
{
|
||||||
// Get the characters from the multi-byte strings and put them in an
|
// Get the characters from the multi-byte strings and put them in an
|
||||||
// int array for easy access.
|
// int array for easy access.
|
||||||
badlen = 0;
|
badlen = 0;
|
||||||
@@ -6443,9 +6361,6 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
|
|||||||
wgoodword[goodlen++] = mb_cptr2char_adv(&p);
|
wgoodword[goodlen++] = mb_cptr2char_adv(&p);
|
||||||
}
|
}
|
||||||
wgoodword[goodlen++] = 0;
|
wgoodword[goodlen++] = 0;
|
||||||
} else {
|
|
||||||
badlen = (int)STRLEN(badword) + 1;
|
|
||||||
goodlen = (int)STRLEN(goodword) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use "cnt" as an array: CNT(badword_idx, goodword_idx).
|
// We use "cnt" as an array: CNT(badword_idx, goodword_idx).
|
||||||
@@ -6458,17 +6373,12 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
|
|||||||
|
|
||||||
for (i = 1; i <= badlen; ++i) {
|
for (i = 1; i <= badlen; ++i) {
|
||||||
CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL;
|
CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL;
|
||||||
for (j = 1; j <= goodlen; ++j) {
|
for (j = 1; j <= goodlen; j++) {
|
||||||
if (l_has_mbyte) {
|
bc = wbadword[i - 1];
|
||||||
bc = wbadword[i - 1];
|
gc = wgoodword[j - 1];
|
||||||
gc = wgoodword[j - 1];
|
if (bc == gc) {
|
||||||
} else {
|
|
||||||
bc = badword[i - 1];
|
|
||||||
gc = goodword[j - 1];
|
|
||||||
}
|
|
||||||
if (bc == gc)
|
|
||||||
CNT(i, j) = CNT(i - 1, j - 1);
|
CNT(i, j) = CNT(i - 1, j - 1);
|
||||||
else {
|
} else {
|
||||||
// Use a better score when there is only a case difference.
|
// Use a better score when there is only a case difference.
|
||||||
if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
|
if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
|
||||||
CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1);
|
CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1);
|
||||||
@@ -6483,13 +6393,8 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i > 1 && j > 1) {
|
if (i > 1 && j > 1) {
|
||||||
if (l_has_mbyte) {
|
pbc = wbadword[i - 2];
|
||||||
pbc = wbadword[i - 2];
|
pgc = wgoodword[j - 2];
|
||||||
pgc = wgoodword[j - 2];
|
|
||||||
} else {
|
|
||||||
pbc = badword[i - 2];
|
|
||||||
pgc = goodword[j - 2];
|
|
||||||
}
|
|
||||||
if (bc == pgc && pbc == gc) {
|
if (bc == pgc && pbc == gc) {
|
||||||
t = SCORE_SWAP + CNT(i - 2, j - 2);
|
t = SCORE_SWAP + CNT(i - 2, j - 2);
|
||||||
if (t < CNT(i, j))
|
if (t < CNT(i, j))
|
||||||
@@ -6519,147 +6424,7 @@ static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
|
|||||||
// for multi-byte characters.
|
// for multi-byte characters.
|
||||||
static int spell_edit_score_limit(slang_T *slang, char_u *badword, char_u *goodword, int limit)
|
static int spell_edit_score_limit(slang_T *slang, char_u *badword, char_u *goodword, int limit)
|
||||||
{
|
{
|
||||||
limitscore_T stack[10]; // allow for over 3 * 2 edits
|
return spell_edit_score_limit_w(slang, badword, goodword, limit);
|
||||||
int stackidx;
|
|
||||||
int bi, gi;
|
|
||||||
int bi2, gi2;
|
|
||||||
int bc, gc;
|
|
||||||
int score;
|
|
||||||
int score_off;
|
|
||||||
int minscore;
|
|
||||||
int round;
|
|
||||||
|
|
||||||
// Multi-byte characters require a bit more work, use a different function
|
|
||||||
// to avoid testing "has_mbyte" quite often.
|
|
||||||
if (has_mbyte)
|
|
||||||
return spell_edit_score_limit_w(slang, badword, goodword, limit);
|
|
||||||
|
|
||||||
// The idea is to go from start to end over the words. So long as
|
|
||||||
// characters are equal just continue, this always gives the lowest score.
|
|
||||||
// When there is a difference try several alternatives. Each alternative
|
|
||||||
// increases "score" for the edit distance. Some of the alternatives are
|
|
||||||
// pushed unto a stack and tried later, some are tried right away. At the
|
|
||||||
// end of the word the score for one alternative is known. The lowest
|
|
||||||
// possible score is stored in "minscore".
|
|
||||||
stackidx = 0;
|
|
||||||
bi = 0;
|
|
||||||
gi = 0;
|
|
||||||
score = 0;
|
|
||||||
minscore = limit + 1;
|
|
||||||
|
|
||||||
for (;; ) {
|
|
||||||
// Skip over an equal part, score remains the same.
|
|
||||||
for (;; ) {
|
|
||||||
bc = badword[bi];
|
|
||||||
gc = goodword[gi];
|
|
||||||
if (bc != gc) // stop at a char that's different
|
|
||||||
break;
|
|
||||||
if (bc == NUL) { // both words end
|
|
||||||
if (score < minscore)
|
|
||||||
minscore = score;
|
|
||||||
goto pop; // do next alternative
|
|
||||||
}
|
|
||||||
++bi;
|
|
||||||
++gi;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gc == NUL) { // goodword ends, delete badword chars
|
|
||||||
do {
|
|
||||||
if ((score += SCORE_DEL) >= minscore)
|
|
||||||
goto pop; // do next alternative
|
|
||||||
} while (badword[++bi] != NUL);
|
|
||||||
minscore = score;
|
|
||||||
} else if (bc == NUL) { // badword ends, insert badword chars
|
|
||||||
do {
|
|
||||||
if ((score += SCORE_INS) >= minscore)
|
|
||||||
goto pop; // do next alternative
|
|
||||||
} while (goodword[++gi] != NUL);
|
|
||||||
minscore = score;
|
|
||||||
} else { // both words continue
|
|
||||||
// If not close to the limit, perform a change. Only try changes
|
|
||||||
// that may lead to a lower score than "minscore".
|
|
||||||
// round 0: try deleting a char from badword
|
|
||||||
// round 1: try inserting a char in badword
|
|
||||||
for (round = 0; round <= 1; ++round) {
|
|
||||||
score_off = score + (round == 0 ? SCORE_DEL : SCORE_INS);
|
|
||||||
if (score_off < minscore) {
|
|
||||||
if (score_off + SCORE_EDIT_MIN >= minscore) {
|
|
||||||
// Near the limit, rest of the words must match. We
|
|
||||||
// can check that right now, no need to push an item
|
|
||||||
// onto the stack.
|
|
||||||
bi2 = bi + 1 - round;
|
|
||||||
gi2 = gi + round;
|
|
||||||
while (goodword[gi2] == badword[bi2]) {
|
|
||||||
if (goodword[gi2] == NUL) {
|
|
||||||
minscore = score_off;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++bi2;
|
|
||||||
++gi2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// try deleting/inserting a character later
|
|
||||||
stack[stackidx].badi = bi + 1 - round;
|
|
||||||
stack[stackidx].goodi = gi + round;
|
|
||||||
stack[stackidx].score = score_off;
|
|
||||||
++stackidx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (score + SCORE_SWAP < minscore) {
|
|
||||||
// If swapping two characters makes a match then the
|
|
||||||
// substitution is more expensive, thus there is no need to
|
|
||||||
// try both.
|
|
||||||
if (gc == badword[bi + 1] && bc == goodword[gi + 1]) {
|
|
||||||
// Swap two characters, that is: skip them.
|
|
||||||
gi += 2;
|
|
||||||
bi += 2;
|
|
||||||
score += SCORE_SWAP;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Substitute one character for another which is the same
|
|
||||||
// thing as deleting a character from both goodword and badword.
|
|
||||||
// Use a better score when there is only a case difference.
|
|
||||||
if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
|
|
||||||
score += SCORE_ICASE;
|
|
||||||
else {
|
|
||||||
// For a similar character use SCORE_SIMILAR.
|
|
||||||
if (slang != NULL
|
|
||||||
&& slang->sl_has_map
|
|
||||||
&& similar_chars(slang, gc, bc))
|
|
||||||
score += SCORE_SIMILAR;
|
|
||||||
else
|
|
||||||
score += SCORE_SUBST;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (score < minscore) {
|
|
||||||
// Do the substitution.
|
|
||||||
++gi;
|
|
||||||
++bi;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pop:
|
|
||||||
// Get here to try the next alternative, pop it from the stack.
|
|
||||||
if (stackidx == 0) // stack is empty, finished
|
|
||||||
break;
|
|
||||||
|
|
||||||
// pop an item from the stack
|
|
||||||
--stackidx;
|
|
||||||
gi = stack[stackidx].goodi;
|
|
||||||
bi = stack[stackidx].badi;
|
|
||||||
score = stack[stackidx].score;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When the score goes over "limit" it may actually be much higher.
|
|
||||||
// Return a very large number to avoid going below the limit when giving a
|
|
||||||
// bonus.
|
|
||||||
if (minscore > limit)
|
|
||||||
return SCORE_MAXMAX;
|
|
||||||
return minscore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multi-byte version of spell_edit_score_limit().
|
// Multi-byte version of spell_edit_score_limit().
|
||||||
|
|||||||
@@ -1221,18 +1221,18 @@ static int read_sal_section(FILE *fd, slang_T *slang)
|
|||||||
return ccnt;
|
return ccnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_mbyte) {
|
// convert the multi-byte strings to wide char strings
|
||||||
// convert the multi-byte strings to wide char strings
|
smp->sm_lead_w = mb_str2wide(smp->sm_lead);
|
||||||
smp->sm_lead_w = mb_str2wide(smp->sm_lead);
|
smp->sm_leadlen = mb_charlen(smp->sm_lead);
|
||||||
smp->sm_leadlen = mb_charlen(smp->sm_lead);
|
if (smp->sm_oneof == NULL) {
|
||||||
if (smp->sm_oneof == NULL)
|
smp->sm_oneof_w = NULL;
|
||||||
smp->sm_oneof_w = NULL;
|
} else {
|
||||||
else
|
smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
|
||||||
smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
|
}
|
||||||
if (smp->sm_to == NULL)
|
if (smp->sm_to == NULL) {
|
||||||
smp->sm_to_w = NULL;
|
smp->sm_to_w = NULL;
|
||||||
else
|
} else {
|
||||||
smp->sm_to_w = mb_str2wide(smp->sm_to);
|
smp->sm_to_w = mb_str2wide(smp->sm_to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1488,72 +1488,61 @@ static int read_compound(FILE *fd, slang_T *slang, int len)
|
|||||||
// Returns SP_*ERROR flags when there is something wrong.
|
// Returns SP_*ERROR flags when there is something wrong.
|
||||||
static int set_sofo(slang_T *lp, char_u *from, char_u *to)
|
static int set_sofo(slang_T *lp, char_u *from, char_u *to)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
garray_T *gap;
|
|
||||||
char_u *s;
|
char_u *s;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int c;
|
|
||||||
int *inp;
|
|
||||||
|
|
||||||
if (has_mbyte) {
|
// Use "sl_sal" as an array with 256 pointers to a list of wide
|
||||||
// Use "sl_sal" as an array with 256 pointers to a list of wide
|
// characters. The index is the low byte of the character.
|
||||||
// characters. The index is the low byte of the character.
|
// The list contains from-to pairs with a terminating NUL.
|
||||||
// The list contains from-to pairs with a terminating NUL.
|
// sl_sal_first[] is used for latin1 "from" characters.
|
||||||
// sl_sal_first[] is used for latin1 "from" characters.
|
garray_T *gap = &lp->sl_sal;
|
||||||
gap = &lp->sl_sal;
|
ga_init(gap, sizeof(int *), 1);
|
||||||
ga_init(gap, sizeof(int *), 1);
|
ga_grow(gap, 256);
|
||||||
ga_grow(gap, 256);
|
memset(gap->ga_data, 0, sizeof(int *) * 256);
|
||||||
memset(gap->ga_data, 0, sizeof(int *) * 256);
|
gap->ga_len = 256;
|
||||||
gap->ga_len = 256;
|
|
||||||
|
|
||||||
// First count the number of items for each list. Temporarily use
|
// First count the number of items for each list. Temporarily use
|
||||||
// sl_sal_first[] for this.
|
// sl_sal_first[] for this.
|
||||||
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
||||||
c = mb_cptr2char_adv((const char_u **)&p);
|
const int c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
MB_CPTR_ADV(s);
|
MB_CPTR_ADV(s);
|
||||||
if (c >= 256) {
|
if (c >= 256) {
|
||||||
lp->sl_sal_first[c & 0xff]++;
|
lp->sl_sal_first[c & 0xff]++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (*p != NUL || *s != NUL) // lengths differ
|
}
|
||||||
return SP_FORMERROR;
|
if (*p != NUL || *s != NUL) { // lengths differ
|
||||||
|
return SP_FORMERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate the lists.
|
// Allocate the lists.
|
||||||
for (i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; i++) {
|
||||||
if (lp->sl_sal_first[i] > 0) {
|
if (lp->sl_sal_first[i] > 0) {
|
||||||
p = xmalloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
|
p = xmalloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
|
||||||
((int **)gap->ga_data)[i] = (int *)p;
|
((int **)gap->ga_data)[i] = (int *)p;
|
||||||
*(int *)p = 0;
|
*(int *)p = 0;
|
||||||
}
|
|
||||||
|
|
||||||
// Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
|
|
||||||
// list.
|
|
||||||
memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
|
|
||||||
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
|
||||||
c = mb_cptr2char_adv((const char_u **)&p);
|
|
||||||
i = mb_cptr2char_adv((const char_u **)&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 {
|
}
|
||||||
// mapping bytes to bytes is done in sl_sal_first[]
|
|
||||||
if (STRLEN(from) != STRLEN(to))
|
|
||||||
return SP_FORMERROR;
|
|
||||||
|
|
||||||
for (i = 0; to[i] != NUL; ++i)
|
// Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
|
||||||
lp->sl_sal_first[from[i]] = to[i];
|
// list.
|
||||||
lp->sl_sal.ga_len = 1; // indicates we have soundfolding
|
memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
|
||||||
|
for (p = from, s = to; *p != NUL && *s != NUL; ) {
|
||||||
|
const int c = mb_cptr2char_adv((const char_u **)&p);
|
||||||
|
const int i = mb_cptr2char_adv((const char_u **)&s);
|
||||||
|
if (c >= 256) {
|
||||||
|
// Append the from-to chars at the end of the list with
|
||||||
|
// the low byte.
|
||||||
|
int *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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1572,40 +1561,35 @@ static void set_sal_first(slang_T *lp)
|
|||||||
sfirst[i] = -1;
|
sfirst[i] = -1;
|
||||||
}
|
}
|
||||||
smp = (salitem_T *)gap->ga_data;
|
smp = (salitem_T *)gap->ga_data;
|
||||||
for (int i = 0; i < gap->ga_len; ++i) {
|
for (int i = 0; i < gap->ga_len; i++) {
|
||||||
if (has_mbyte)
|
// Use the lowest byte of the first character. For latin1 it's
|
||||||
// Use the lowest byte of the first character. For latin1 it's
|
// the character, for other encodings it should differ for most
|
||||||
// the character, for other encodings it should differ for most
|
// characters.
|
||||||
// characters.
|
c = *smp[i].sm_lead_w & 0xff;
|
||||||
c = *smp[i].sm_lead_w & 0xff;
|
|
||||||
else
|
|
||||||
c = *smp[i].sm_lead;
|
|
||||||
if (sfirst[c] == -1) {
|
if (sfirst[c] == -1) {
|
||||||
sfirst[c] = i;
|
sfirst[c] = i;
|
||||||
if (has_mbyte) {
|
|
||||||
int n;
|
|
||||||
|
|
||||||
// Make sure all entries with this byte are following each
|
// Make sure all entries with this byte are following each
|
||||||
// other. Move the ones that are in the wrong position. Do
|
// other. Move the ones that are in the wrong position. Do
|
||||||
// keep the same ordering!
|
// keep the same ordering!
|
||||||
while (i + 1 < gap->ga_len
|
while (i + 1 < gap->ga_len
|
||||||
&& (*smp[i + 1].sm_lead_w & 0xff) == c)
|
&& (*smp[i + 1].sm_lead_w & 0xff) == c) {
|
||||||
// Skip over entry with same index byte.
|
// Skip over entry with same index byte.
|
||||||
++i;
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
for (n = 1; i + n < gap->ga_len; ++n)
|
for (int n = 1; i + n < gap->ga_len; n++) {
|
||||||
if ((*smp[i + n].sm_lead_w & 0xff) == c) {
|
if ((*smp[i + n].sm_lead_w & 0xff) == c) {
|
||||||
salitem_T tsal;
|
salitem_T tsal;
|
||||||
|
|
||||||
// Move entry with same index byte after the entries
|
// Move entry with same index byte after the entries
|
||||||
// we already found.
|
// we already found.
|
||||||
++i;
|
i++;
|
||||||
--n;
|
n--;
|
||||||
tsal = smp[i + n];
|
tsal = smp[i + n];
|
||||||
memmove(smp + i + 1, smp + i,
|
memmove(smp + i + 1, smp + i, sizeof(salitem_T) * n);
|
||||||
sizeof(salitem_T) * n);
|
smp[i] = tsal;
|
||||||
smp[i] = tsal;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2454,12 +2438,8 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
|
|||||||
// upper-case letter.
|
// upper-case letter.
|
||||||
if (aff_entry->ae_cond != NULL) {
|
if (aff_entry->ae_cond != NULL) {
|
||||||
char_u buf[MAXLINELEN];
|
char_u buf[MAXLINELEN];
|
||||||
if (has_mbyte) {
|
onecap_copy(items[4], buf, true);
|
||||||
onecap_copy(items[4], buf, true);
|
aff_entry->ae_cond = getroom_save(spin, buf);
|
||||||
aff_entry->ae_cond = getroom_save(
|
|
||||||
spin, buf);
|
|
||||||
} else
|
|
||||||
*aff_entry->ae_cond = c_up;
|
|
||||||
if (aff_entry->ae_cond != NULL) {
|
if (aff_entry->ae_cond != NULL) {
|
||||||
sprintf((char *)buf, "^%s",
|
sprintf((char *)buf, "^%s",
|
||||||
aff_entry->ae_cond);
|
aff_entry->ae_cond);
|
||||||
@@ -3373,13 +3353,9 @@ store_aff_word (
|
|||||||
p = word;
|
p = word;
|
||||||
if (ae->ae_chop != NULL) {
|
if (ae->ae_chop != NULL) {
|
||||||
// Skip chop string.
|
// Skip chop string.
|
||||||
if (has_mbyte) {
|
i = mb_charlen(ae->ae_chop);
|
||||||
i = mb_charlen(ae->ae_chop);
|
for (; i > 0; i--) {
|
||||||
for (; i > 0; i--) {
|
MB_PTR_ADV(p);
|
||||||
MB_PTR_ADV(p);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p += STRLEN(ae->ae_chop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STRCAT(newword, p);
|
STRCAT(newword, p);
|
||||||
|
|||||||
@@ -2960,11 +2960,7 @@ static int check_keyword_id(
|
|||||||
char_u *const kwp = line + startcol;
|
char_u *const kwp = line + startcol;
|
||||||
int kwlen = 0;
|
int kwlen = 0;
|
||||||
do {
|
do {
|
||||||
if (has_mbyte) {
|
kwlen += utfc_ptr2len(kwp + kwlen);
|
||||||
kwlen += (*mb_ptr2len)(kwp + kwlen);
|
|
||||||
} else {
|
|
||||||
kwlen++;
|
|
||||||
}
|
|
||||||
} while (vim_iswordp_buf(kwp + kwlen, syn_buf));
|
} while (vim_iswordp_buf(kwp + kwlen, syn_buf));
|
||||||
|
|
||||||
if (kwlen > MAXKEYWLEN) {
|
if (kwlen > MAXKEYWLEN) {
|
||||||
|
|||||||
@@ -6151,11 +6151,7 @@ file_name_in_line (
|
|||||||
// Skip over the "\" in "\ ".
|
// Skip over the "\" in "\ ".
|
||||||
++len;
|
++len;
|
||||||
}
|
}
|
||||||
if (has_mbyte) {
|
len += (size_t)(utfc_ptr2len(ptr + len));
|
||||||
len += (size_t)(*mb_ptr2len)(ptr + len);
|
|
||||||
} else {
|
|
||||||
++len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user