To: vim-dev@vim.org
Subject: patch 7.1.067
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
------------
Patch 7.1.067
Problem: 'thesaurus' doesn't work when 'infercase' is set. (Mohsin)
Solution: Don't copy the characters being completed but check the case and
apply it to the suggested word. Also fix that the first word in
the thesaurus line is not used. (Martin Toft)
Files: src/edit.c
*** ../vim-7.1.066/src/edit.c Sun Jul 29 15:02:34 2007
--- src/edit.c Sat Aug 11 17:16:51 2007
***************
*** 2057,2063 ****
* case of the originally typed text is used, and the case of the completed
* text is inferred, ie this tries to work out what case you probably wanted
* the rest of the word to be in -- webb
- * TODO: make this work for multi-byte characters.
*/
int
ins_compl_add_infercase(str, len, icase, fname, dir, flags)
--- 2057,2062 ----
***************
*** 2068,2121 ****
int dir;
int flags;
{
int has_lower = FALSE;
int was_letter = FALSE;
- int idx;
! if (p_ic && curbuf->b_p_inf && len < IOSIZE)
{
! /* Infer case of completed part -- webb */
! /* Use IObuff, str would change text in buffer! */
! vim_strncpy(IObuff, str, len);
! /* Rule 1: Were any chars converted to lower? */
! for (idx = 0; idx < compl_length; ++idx)
{
! if (islower(compl_orig_text[idx]))
{
! has_lower = TRUE;
! if (isupper(IObuff[idx]))
! {
! /* Rule 1 is satisfied */
! for (idx = compl_length; idx < len; ++idx)
! IObuff[idx] = TOLOWER_LOC(IObuff[idx]);
! break;
! }
}
}
! /*
! * Rule 2: No lower case, 2nd consecutive letter converted to
! * upper case.
! */
! if (!has_lower)
{
! for (idx = 0; idx < compl_length; ++idx)
{
! if (was_letter && isupper(compl_orig_text[idx])
! && islower(IObuff[idx]))
{
! /* Rule 2 is satisfied */
! for (idx = compl_length; idx < len; ++idx)
! IObuff[idx] = TOUPPER_LOC(IObuff[idx]);
! break;
}
- was_letter = isalpha(compl_orig_text[idx]);
}
- }
! /* Copy the original case of the part we typed */
! STRNCPY(IObuff, compl_orig_text, compl_length);
return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
flags, FALSE);
--- 2067,2213 ----
int dir;
int flags;
{
+ char_u *p;
+ int i, c;
+ int actual_len; /* Take multi-byte characters */
+ int actual_compl_length; /* into account. */
+ int *wca; /* Wide character array. */
int has_lower = FALSE;
int was_letter = FALSE;
! if (p_ic && curbuf->b_p_inf)
{
! /* Infer case of completed part. */
! /* Find actual length of completion. */
! #ifdef FEAT_MBYTE
! if (has_mbyte)
{
! p = str;
! actual_len = 0;
! while (*p != NUL)
{
! mb_ptr_adv(p);
! ++actual_len;
}
}
+ else
+ #endif
+ actual_len = len;
! /* Find actual length of original text. */
! #ifdef FEAT_MBYTE
! if (has_mbyte)
{
! p = compl_orig_text;
! actual_compl_length = 0;
! while (*p != NUL)
{
! mb_ptr_adv(p);
! ++actual_compl_length;
! }
! }
! else
! #endif
! actual_compl_length = compl_length;
!
! /* Allocate wide character array for the completion and fill it. */
! wca = (int *)alloc(actual_len * sizeof(int));
! if (wca != NULL)
! {
! p = str;
! for (i = 0; i < actual_len; ++i)
! #ifdef FEAT_MBYTE
! if (has_mbyte)
! wca[i] = mb_ptr2char_adv(&p);
! else
! #endif
! wca[i] = *(p++);
!
! /* Rule 1: Were any chars converted to lower? */
! p = compl_orig_text;
! for (i = 0; i < actual_compl_length; ++i)
! {
! #ifdef FEAT_MBYTE
! if (has_mbyte)
! c = mb_ptr2char_adv(&p);
! else
! #endif
! c = *(p++);
! if (MB_ISLOWER(c))
{
! has_lower = TRUE;
! if (MB_ISUPPER(wca[i]))
! {
! /* Rule 1 is satisfied. */
! for (i = actual_compl_length; i < actual_len; ++i)
! wca[i] = MB_TOLOWER(wca[i]);
! break;
! }
}
}
! /*
! * Rule 2: No lower case, 2nd consecutive letter converted to
! * upper case.
! */
! if (!has_lower)
! {
! p = compl_orig_text;
! for (i = 0; i < actual_compl_length; ++i)
! {
! #ifdef FEAT_MBYTE
! if (has_mbyte)
! c = mb_ptr2char_adv(&p);
! else
! #endif
! c = *(p++);
! if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
! {
! /* Rule 2 is satisfied. */
! for (i = actual_compl_length; i < actual_len; ++i)
! wca[i] = MB_TOUPPER(wca[i]);
! break;
! }
! was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
! }
! }
!
! /* Copy the original case of the part we typed. */
! p = compl_orig_text;
! for (i = 0; i < actual_compl_length; ++i)
! {
! #ifdef FEAT_MBYTE
! if (has_mbyte)
! c = mb_ptr2char_adv(&p);
! else
! #endif
! c = *(p++);
! if (MB_ISLOWER(c))
! wca[i] = MB_TOLOWER(wca[i]);
! else if (MB_ISUPPER(c))
! wca[i] = MB_TOUPPER(wca[i]);
! }
!
! /*
! * Generate encoding specific output from wide character array.
! * Multi-byte characters can occupy up to five bytes more than
! * ASCII characters, and we also need one byte for NUL, so stay
! * six bytes away from the edge of IObuff.
! */
! p = IObuff;
! i = 0;
! while (i < actual_len && (p - IObuff + 6) < IOSIZE)
! #ifdef FEAT_MBYTE
! if (has_mbyte)
! p += mb_char2bytes(wca[i++], p);
! else
! #endif
! *(p++) = wca[i++];
! *p = NUL;
!
! vim_free(wca);
! }
return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
flags, FALSE);
***************
*** 2842,2847 ****
--- 2934,2940 ----
/*
* Add the other matches on the line
*/
+ ptr = buf;
while (!got_int)
{
/* Find start of the next word. Skip white
***************
*** 2851,2857 ****
break;
wstart = ptr;
! /* Find end of the word and add it. */
#ifdef FEAT_MBYTE
if (has_mbyte)
/* Japanese words may have characters in
--- 2944,2950 ----
break;
wstart = ptr;
! /* Find end of the word. */
#ifdef FEAT_MBYTE
if (has_mbyte)
/* Japanese words may have characters in
***************
*** 2868,2876 ****
else
#endif
ptr = find_word_end(ptr);
! add_r = ins_compl_add_infercase(wstart,
! (int)(ptr - wstart),
! p_ic, files[i], *dir, 0);
}
}
if (add_r == OK)
--- 2961,2972 ----
else
#endif
ptr = find_word_end(ptr);
!
! /* Add the word. Skip the regexp match. */
! if (wstart != regmatch->startp[0])
! add_r = ins_compl_add_infercase(wstart,
! (int)(ptr - wstart),
! p_ic, files[i], *dir, 0);
}
}
if (add_r == OK)
*** ../vim-7.1.066/src/version.c Sun Aug 12 15:50:26 2007
--- src/version.c Sun Aug 12 16:36:34 2007
***************
*** 668,669 ****
--- 668,671 ----
{ /* Add new patch number below this line */
+ /**/
+ 67,
/**/
--
hundred-and-one symptoms of being an internet addict:
128. You can access the Net -- via your portable and cellular phone.
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///