Hello,

Sergey Klimov attached a patch for this to one Ubuntu bug
(http://launchpad.net/bugs/655060). To not let this patch get unnoticed,
I forward it to you for review.

Thanks,
Michael

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff -Naur vim71.orig/runtime/doc/options.txt vim71/runtime/doc/options.txt
--- vim71.orig/runtime/doc/options.txt	2007-05-12 13:18:47.000000000 +0300
+++ vim71/runtime/doc/options.txt	2007-07-14 01:30:15.000000000 +0300
@@ -4144,9 +4144,6 @@
 	be able to execute Normal mode commands.
 	This is the opposite of the 'keymap' option, where characters are
 	mapped in Insert mode.
-	This only works for 8-bit characters.  The value of 'langmap' may be
-	specified with multi-byte characters (e.g., UTF-8), but only the lower
-	8 bits of each character will be used.
 
 	Example (for Greek, in UTF-8):				*greek*  >
 	    :set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz
diff -Naur vim71.orig/runtime/doc/todo.txt vim71/runtime/doc/todo.txt
--- vim71.orig/runtime/doc/todo.txt	2007-05-12 13:18:47.000000000 +0300
+++ vim71/runtime/doc/todo.txt	2007-07-14 01:33:14.000000000 +0300
@@ -1804,8 +1804,6 @@
     Support CTRL-K _{mnemonic}_
 7   In "-- INSERT (lang) --" show the name of the keymap used instead of
     "lang". (Ilya Dogolazky)
--   Make 'langmap' accept multi-byte characters.
-	Patch from Konstantin Korikov, 2006 Oct 15.
 -   Make 'breakat' accept multi-byte characters.  Problem: can't use a lookup
     table anymore (breakat_flags[]).
     Simplistic solution: when 'formatoptions' contains "m" also break a line
diff -Naur vim71.orig/src/globals.h vim71/src/globals.h
--- vim71.orig/src/globals.h	2007-05-07 22:44:26.000000000 +0300
+++ vim71/src/globals.h	2007-07-14 01:30:15.000000000 +0300
@@ -1058,7 +1058,19 @@
 #endif
 
 #ifdef FEAT_LANGMAP
-EXTERN char_u	langmap_mapchar[256];	/* mapping for language keys */
+/* mapping for language keys */
+#ifdef FEAT_MBYTE
+/* With multi-byte support use growarray of mapping entries */
+typedef struct langmap_entry {
+    int from;
+    char_u to;
+} langmap_entry_T;
+
+EXTERN garray_T langmap_mapchar;
+#else
+/* Without multi-byte support use single mapping array */
+EXTERN char_u	langmap_mapchar[256];
+#endif
 #endif
 
 #ifdef FEAT_WILDMENU
diff -Naur vim71.orig/src/macros.h vim71/src/macros.h
--- vim71.orig/src/macros.h	2007-05-07 22:38:22.000000000 +0300
+++ vim71/src/macros.h	2007-07-14 01:30:15.000000000 +0300
@@ -125,15 +125,32 @@
 #ifdef FEAT_LANGMAP
 /*
  * Adjust chars in a language according to 'langmap' option.
- * NOTE that there is NO overhead if 'langmap' is not set; but even
- * when set we only have to do 2 ifs and an array lookup.
+ * NOTE that there is NO overhead if 'langmap' is not set.
  * Don't apply 'langmap' if the character comes from the Stuff buffer.
  * The do-while is just to ignore a ';' after the macro.
  */
+#ifdef FEAT_MBYTE
 # define LANGMAP_ADJUST(c, condition) do { \
-	if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
-	    c = langmap_mapchar[c]; \
+	if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) { \
+	    langmap_entry_T *e = (langmap_entry_T*)(langmap_mapchar.ga_data); \
+	    int a = 0, b = langmap_mapchar.ga_len; \
+	    while (a != b) { \
+		int i = (a + b) / 2; \
+		int d = e[i].from - (c); \
+		if (d == 0) { \
+		    c = e[i].to; \
+		    break; \
+		} \
+		if (d < 0) a = i + 1; else b = i; \
+	    } \
+	} \
     } while (0)
+#else
+# define LANGMAP_ADJUST(c, condition) do { \
+        if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
+            c = langmap_mapchar[c]; \
+    } while (0)
+#endif
 #endif
 
 /*
diff -Naur vim71.orig/src/option.c vim71/src/option.c
--- vim71.orig/src/option.c	2007-05-01 14:26:10.000000000 +0300
+++ vim71/src/option.c	2007-07-14 01:30:15.000000000 +0300
@@ -10062,21 +10062,74 @@
  * other characters can be translated too).
  */
 
-/*
+/* #ifdef FEAT_MBYTE
+ * garray_T langmap_mapchar;
+ * langmap_mapchar.ga_data is array of langmap_entry_T.
+ * Normally maps wide characters to an <128 ascii char; used to
+ * "translate" native lang chars in normal mode or some cases of
+ * insert mode without having to tediously switch lang mode back&forth.
+ * #else
  * char_u langmap_mapchar[256];
  * Normally maps each of the 128 upper chars to an <128 ascii char; used to
  * "translate" native lang chars in normal mode or some cases of
  * insert mode without having to tediously switch lang mode back&forth.
+ * #endif
  */
 
     static void
 langmap_init()
 {
+#ifdef FEAT_MBYTE
+    ga_init2(&langmap_mapchar, sizeof(langmap_entry_T), 8);
+#else
     int i;
 
     for (i = 0; i < 256; i++)		/* we init with a-one-to one map */
 	langmap_mapchar[i] = i;
+#endif
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Search for a entry in langmap_mapchar for `from'.
+ * if found set entry `to' field to `to'. if not found
+ * insert new entry with `from' and `to' fields set to
+ * `from' and `to' respectively.
+ */
+    static void
+langmap_set_entry(from, to)
+    int from;
+    char_u to;
+{
+    langmap_entry_T *entries = (langmap_entry_T*)(langmap_mapchar.ga_data);
+    int a = 0, b = langmap_mapchar.ga_len;
+
+    while (a != b)
+    {
+	int i = (a + b) / 2;
+	int d = entries[i].from - from;
+	if (d == 0)
+	{
+	    entries[i].to = to;
+	    return;
+	}
+	if (d < 0) a = i + 1; else b = i;
+    }
+
+    if (ga_grow(&langmap_mapchar, 1) != OK) {
+	EMSG(_("EXXX: 'langmap_set_entry': Out of memory"));
+	return;
+    }
+
+    /* insert new entry at position a */
+    entries = (langmap_entry_T*)(langmap_mapchar.ga_data) + a;
+    mch_memmove(entries + 1, entries,
+	    (langmap_mapchar.ga_len - a) * sizeof(langmap_entry_T));
+    ++langmap_mapchar.ga_len;
+    entries[0].from = from;
+    entries[0].to = to;
 }
+#endif
 
 /*
  * Called when langmap option is set; the language map can be
@@ -10089,7 +10142,11 @@
     char_u  *p2;
     int	    from, to;
 
+#ifdef FEAT_MBYTE
+    ga_clear(&langmap_mapchar);		    /* clear the previous map first */
+#else
     langmap_init();			    /* back to one-to-one map first */
+#endif
 
     for (p = p_langmap; p[0] != NUL; )
     {
@@ -10132,6 +10189,9 @@
 #else
 		to = p2[0];
 #endif
+		if (to < 0 || to >= 128)
+		    MSG_ATTR(_("WXXX: 'langmap': Mapping to non-ASCII character"),
+			    hl_attr(HLF_W));
 	    }
 	    if (to == NUL)
 	    {
@@ -10139,7 +10199,12 @@
 							     transchar(from));
 		return;
 	    }
+
+#ifdef FEAT_MBYTE
+	    langmap_set_entry(from, to);
+#else
 	    langmap_mapchar[from & 255] = to;
+#endif
 
 	    /* Advance to next pair */
 	    mb_ptr_adv(p);

Raspunde prin e-mail lui