]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0645: Composing chars no longer accepted in end-id abbr v9.2.0645
authorzeertzjq <zeertzjq@outlook.com>
Sun, 14 Jun 2026 15:39:26 +0000 (15:39 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 14 Jun 2026 15:39:26 +0000 (15:39 +0000)
Problem:  Composing chars are no longer accepted in end-id abbreviation
          (after 9.2.0629).
Solution: Unescape all chars using vim_unescape_csi() instead of using
          mb_unescape() on individual chars, so that mb_ptr2len() and
          MB_PTR_ADV() can still be used.

closes: #20514

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/map.c
src/proto/map.pro
src/testdir/test_mapping.vim
src/version.c

index 50d7ee4bcb2ce6d52b7d24d33ccad1ffb06a5a92..5970b3f5a520380a10752c1867bf6d06234fda1e 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -660,26 +660,26 @@ do_map(
                // vi-compatible way.
                if (has_mbyte)
                {
-                   int first, last;
-                   int same = -1;
-                   char_u *p_char;
-
-                   p = keys;
-                   p_char = mb_unescape(&p);
-                   if (p_char == NULL)
-                       p_char = p++;
-                   first = vim_iswordp(p_char);
+                   int         first, last;
+                   int         same = -1;
+                   char_u      keys_unescaped[MAXMAPLEN + 1];
+                   size_t      keys_unescaped_len;
+
+                   mch_memmove(keys_unescaped, keys, (size_t)(len + 1));
+                   keys_unescaped_len = vim_unescape_csi(keys_unescaped);
+                   p = keys_unescaped;
+
+                   first = vim_iswordp(p);
                    last = first;
+                   MB_PTR_ADV(p);
                    n = 1;
-                   while (p < keys + len)
+                   while (p < keys_unescaped + keys_unescaped_len)
                    {
-                       ++n;                         // nr of (multi-byte) chars
-                       p_char = mb_unescape(&p);
-                       if (p_char == NULL)
-                           p_char = p++;
-                       last = vim_iswordp(p_char);  // type of last char
+                       ++n;                    // nr of (multi-byte) chars
+                       last = vim_iswordp(p);  // type of last char
                        if (same == -1 && last != first)
-                           same = n - 1;            // count of same char type
+                           same = n - 1;       // count of same char type
+                       MB_PTR_ADV(p);
                    }
                    if (last && n > 2 && same >= 0 && same < n - 1)
                    {
@@ -1687,8 +1687,7 @@ check_abbr(
                if (qe != NULL)
                {
                    q = qe;
-                   vim_unescape_csi(q);
-                   qlen = (int)STRLEN(q);
+                   qlen = (int)vim_unescape_csi(q);
                }
            }
 
@@ -1908,8 +1907,9 @@ vim_strsave_escape_csi(char_u *p)
 /*
  * Remove escaping from CSI and K_SPECIAL characters.  Reverse of
  * vim_strsave_escape_csi().  Works in-place.
+ * Returns the number of bytes in the unescaped string.
  */
-    void
+    size_t
 vim_unescape_csi(char_u *p)
 {
     char_u     *s = p, *d = p;
@@ -1931,6 +1931,7 @@ vim_unescape_csi(char_u *p)
            *d++ = *s++;
     }
     *d = NUL;
+    return (size_t)(d - p);
 }
 
 /*
index d696aabcd7bc095bc8439f5bc9acbe446f01d91e..5f736f5047f487a28b5a8bc6269df44095c6c68e 100644 (file)
@@ -12,7 +12,7 @@ int ExpandMappings(char_u *pat, regmatch_T *regmatch, int *numMatches, char_u **
 int check_abbr(int c, char_u *ptr, int col, int mincol);
 char_u *eval_map_expr(mapblock_T *mp, int c);
 char_u *vim_strsave_escape_csi(char_u *p);
-void vim_unescape_csi(char_u *p);
+size_t vim_unescape_csi(char_u *p);
 int makemap(FILE *fd, buf_T *buf);
 int put_escstr(FILE *fd, char_u *strstart, int what);
 void check_map_keycodes(void);
index 635193ebd34f0b6d1b883aaffd230b8c3acd2416..d181bbf396ab88376201c68af49285ad07c3b0fc 100644 (file)
@@ -28,6 +28,18 @@ func Test_abbreviation()
   iunab abc;
   iunab ;
 
+  " abbreviation with composing chars (end-id)
+  inoreab ..ã a^~
+  inoreab ..β̃ β^~
+  inoreab ..π̃ π^~
+  inoreab ..Λ̃ Λ^~
+  call feedkeys("Go..ã ..β̃ ..π̃ ..Λ̃ \<Esc>", "xt")
+  call assert_equal('a^~ β^~ π^~ Λ^~ ', getline('$'))
+  iunab ..ã
+  iunab ..β̃
+  iunab ..π̃
+  iunab ..Λ̃
+
   bwipe!
 endfunc
 
index f00b31d09b5c1436dbf05b1b8d88023241a12d40..4a8bfe821302753584e9ada9facb7fd824d7f876 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    645,
 /**/
     644,
 /**/