changeset 1353:87401adbf5fc v7.1.067

updated for version 7.1-067
author vimboss
date Sun, 12 Aug 2007 14:38:46 +0000
parents c544a3507e83
children 10a1b67c0885
files src/edit.c src/version.c
diffstat 2 files changed, 143 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/edit.c
+++ b/src/edit.c
@@ -2057,7 +2057,6 @@ vim_is_ctrl_x_key(c)
  * 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)
@@ -2068,54 +2067,147 @@ ins_compl_add_infercase(str, len, icase,
     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;
-    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]))
+
+    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)
 	    {
-		has_lower = TRUE;
-		if (isupper(IObuff[idx]))
+		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))
 		{
-		    /* Rule 1 is satisfied */
-		    for (idx = compl_length; idx < len; ++idx)
-			IObuff[idx] = TOLOWER_LOC(IObuff[idx]);
-		    break;
+		    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)
-	{
-	    for (idx = 0; idx < compl_length; ++idx)
+
+	    /*
+	     * 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)
 	    {
-		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]);
+#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]);
 	    }
-	}
-
-	/* Copy the original case of the part we typed */
-	STRNCPY(IObuff, compl_orig_text, compl_length);
+
+	    /* 
+	     * 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,6 +2934,7 @@ ins_compl_files(count, files, thesaurus,
 			/*
 			 * Add the other matches on the line
 			 */
+			ptr = buf;
 			while (!got_int)
 			{
 			    /* Find start of the next word.  Skip white
@@ -2851,7 +2944,7 @@ ins_compl_files(count, files, thesaurus,
 				break;
 			    wstart = ptr;
 
-			    /* Find end of the word and add it. */
+			    /* Find end of the word. */
 #ifdef FEAT_MBYTE
 			    if (has_mbyte)
 				/* Japanese words may have characters in
@@ -2868,9 +2961,12 @@ ins_compl_files(count, files, thesaurus,
 			    else
 #endif
 				ptr = find_word_end(ptr);
-			    add_r = ins_compl_add_infercase(wstart,
-				    (int)(ptr - wstart),
-				    p_ic, files[i], *dir, 0);
+
+			    /* 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)
--- a/src/version.c
+++ b/src/version.c
@@ -667,6 +667,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    67,
+/**/
     66,
 /**/
     65,