Blob Blame History Raw
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    ///