diff src/option.c @ 1811:d88bdbabfbc6 v7.2.109

updated for version 7.2-109
author vimboss
date Sat, 21 Feb 2009 19:28:48 +0000
parents 5d84650b569c
children fbecb12e37f5
line wrap: on
line diff
--- a/src/option.c
+++ b/src/option.c
@@ -10153,25 +10153,110 @@ wc_use_keyname(varp, wcp)
 
 #ifdef FEAT_LANGMAP
 /*
- * Any character has an equivalent character.  This is used for keyboards that
- * have a special language mode that sends characters above 128 (although
- * other characters can be translated too).
- */
-
-/*
- * 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.
- */
+ * Any character has an equivalent 'langmap' character.  This is used for
+ * keyboards that have a special language mode that sends characters above
+ * 128 (although other characters can be translated too).  The "to" field is a
+ * Vim command character.  This avoids having to switch the keyboard back to
+ * ASCII mode when leaving Insert mode.
+ *
+ * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
+ * commands.
+ * When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of
+ * langmap_entry_T.  This does the same as langmap_mapchar[] for characters >=
+ * 256.
+ */
+# ifdef FEAT_MBYTE
+/*
+ * With multi-byte support use growarray for 'langmap' chars >= 256
+ */
+typedef struct
+{
+    int	    from;
+    int     to;
+} langmap_entry_T;
+
+static garray_T langmap_mapga;
+static void langmap_set_entry __ARGS((int from, int to));
+
+/*
+ * Search for an entry in "langmap_mapga" for "from".  If found set the "to"
+ * field.  If not found insert a new entry at the appropriate location.
+ */
+    static void
+langmap_set_entry(from, to)
+    int    from;
+    int    to;
+{
+    langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
+    int             a = 0;
+    int             b = langmap_mapga.ga_len;
+
+    /* Do a binary search for an existing entry. */
+    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_mapga, 1) != OK)
+	return;  /* out of memory */
+
+    /* insert new entry at position "a" */
+    entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a;
+    mch_memmove(entries + 1, entries,
+			(langmap_mapga.ga_len - a) * sizeof(langmap_entry_T));
+    ++langmap_mapga.ga_len;
+    entries[0].from = from;
+    entries[0].to = to;
+}
+
+/*
+ * Apply 'langmap' to multi-byte character "c" and return the result.
+ */
+    int
+langmap_adjust_mb(c)
+    int c;
+{
+    langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
+    int a = 0;
+    int b = langmap_mapga.ga_len;
+
+    while (a != b)
+    {
+	int i = (a + b) / 2;
+	int d = entries[i].from - c;
+
+	if (d == 0)
+	    return entries[i].to;  /* found matching entry */
+	if (d < 0)
+	    a = i + 1;
+	else
+	    b = i;
+    }
+    return c;  /* no entry found, return "c" unmodified */
+}
+# endif
 
     static void
 langmap_init()
 {
     int i;
 
-    for (i = 0; i < 256; i++)		/* we init with a-one-to one map */
-	langmap_mapchar[i] = i;
+    for (i = 0; i < 256; i++)
+	langmap_mapchar[i] = i;	 /* we init with a one-to-one map */
+# ifdef FEAT_MBYTE
+    ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8);
+# endif
 }
 
 /*
@@ -10185,7 +10270,10 @@ langmap_set()
     char_u  *p2;
     int	    from, to;
 
-    langmap_init();			    /* back to one-to-one map first */
+#ifdef FEAT_MBYTE
+    ga_clear(&langmap_mapga);		    /* clear the previous map first */
+#endif
+    langmap_init();			    /* back to one-to-one map */
 
     for (p = p_langmap; p[0] != NUL; )
     {
@@ -10235,7 +10323,13 @@ langmap_set()
 							     transchar(from));
 		return;
 	    }
-	    langmap_mapchar[from & 255] = to;
+
+#ifdef FEAT_MBYTE
+	    if (from >= 256)
+		langmap_set_entry(from, to);
+	    else
+#endif
+		langmap_mapchar[from & 255] = to;
 
 	    /* Advance to next pair */
 	    mb_ptr_adv(p);