diff src/vim9execute.c @ 24128:fcbb1d4df15b v8.2.2605

patch 8.2.2605: Vim9: string index and slice does not include composing chars Commit: https://github.com/vim/vim/commit/0289a093a4d65c6280a3be118d1d3696d1aa74da Author: Bram Moolenaar <Bram@vim.org> Date: Sun Mar 14 18:40:19 2021 +0100 patch 8.2.2605: Vim9: string index and slice does not include composing chars Problem: Vim9: string index and slice does not include composing chars. Solution: Include composing characters. (issue https://github.com/vim/vim/issues/6563)
author Bram Moolenaar <Bram@vim.org>
date Sun, 14 Mar 2021 18:45:03 +0100
parents e8b21a3bb0d5
children 03fc95628eb0
line wrap: on
line diff
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -985,8 +985,9 @@ allocate_if_null(typval_T *tv)
 }
 
 /*
- * Return the character "str[index]" where "index" is the character index.  If
- * "index" is out of range NULL is returned.
+ * Return the character "str[index]" where "index" is the character index,
+ * including composing characters.
+ * If "index" is out of range NULL is returned.
  */
     char_u *
 char_from_string(char_u *str, varnumber_T index)
@@ -1005,7 +1006,7 @@ char_from_string(char_u *str, varnumber_
 	int	clen = 0;
 
 	for (nbyte = 0; nbyte < slen; ++clen)
-	    nbyte += MB_CPTR2LEN(str + nbyte);
+	    nbyte += mb_ptr2len(str + nbyte);
 	nchar = clen + index;
 	if (nchar < 0)
 	    // unlike list: index out of range results in empty string
@@ -1013,15 +1014,15 @@ char_from_string(char_u *str, varnumber_
     }
 
     for (nbyte = 0; nchar > 0 && nbyte < slen; --nchar)
-	nbyte += MB_CPTR2LEN(str + nbyte);
+	nbyte += mb_ptr2len(str + nbyte);
     if (nbyte >= slen)
 	return NULL;
-    return vim_strnsave(str + nbyte, MB_CPTR2LEN(str + nbyte));
+    return vim_strnsave(str + nbyte, mb_ptr2len(str + nbyte));
 }
 
 /*
  * Get the byte index for character index "idx" in string "str" with length
- * "str_len".
+ * "str_len".  Composing characters are included.
  * If going over the end return "str_len".
  * If "idx" is negative count from the end, -1 is the last character.
  * When going over the start return -1.
@@ -1036,7 +1037,7 @@ char_idx2byte(char_u *str, size_t str_le
     {
 	while (nchar > 0 && nbyte < str_len)
 	{
-	    nbyte += MB_CPTR2LEN(str + nbyte);
+	    nbyte += mb_ptr2len(str + nbyte);
 	    --nchar;
 	}
     }
@@ -1056,7 +1057,8 @@ char_idx2byte(char_u *str, size_t str_le
 }
 
 /*
- * Return the slice "str[first:last]" using character indexes.
+ * Return the slice "str[first : last]" using character indexes.  Composing
+ * characters are included.
  * "exclusive" is TRUE for slice().
  * Return NULL when the result is empty.
  */
@@ -1079,7 +1081,7 @@ string_slice(char_u *str, varnumber_T fi
 	end_byte = char_idx2byte(str, slen, last);
 	if (!exclusive && end_byte >= 0 && end_byte < (long)slen)
 	    // end index is inclusive
-	    end_byte += MB_CPTR2LEN(str + end_byte);
+	    end_byte += mb_ptr2len(str + end_byte);
     }
 
     if (start_byte >= (long)slen || end_byte <= start_byte)
@@ -3249,8 +3251,9 @@ call_def_function(
 			res = string_slice(tv->vval.v_string, n1, n2, FALSE);
 		    else
 			// Index: The resulting variable is a string of a
-			// single character.  If the index is too big or
-			// negative the result is empty.
+			// single character (including composing characters).
+			// If the index is too big or negative the result is
+			// empty.
 			res = char_from_string(tv->vval.v_string, n2);
 		    vim_free(tv->vval.v_string);
 		    tv->vval.v_string = res;