Patch 7.2.109
Problem:    'langmap' does not work for multi-byte characters.
Solution:   Add a list of mapped multi-byte characters. (based on work by
            Konstantin Korikov, Agathoklis Hatzimanikas)
Files:      runtime/doc/options.txt, src/edit.c, src/getchar.c, src/macros.h,
            src/normal.c, src/option.c, src/proto/option.pro, src/window.c
    

*** ../vim-7.2.108/runtime/doc/options.txt      Fri Nov 28 10:59:57 2008
--- runtime/doc/options.txt     Wed Feb 11 18:59:34 2009
***************
*** 4175,4183 ****
        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
--- 4188,4193 ----
*** ../vim-7.2.108/src/edit.c   Wed Feb  4 11:19:40 2009
--- src/edit.c  Sat Feb 21 19:54:03 2009
***************
*** 7703,7711 ****
       */
      ++no_mapping;
      regname = plain_vgetc();
- #ifdef FEAT_LANGMAP
      LANGMAP_ADJUST(regname, TRUE);
- #endif
      if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P)
      {
        /* Get a third key for literal register insertion */
--- 7703,7709 ----
***************
*** 7714,7722 ****
        add_to_showcmd_c(literally);
  #endif
        regname = plain_vgetc();
- #ifdef FEAT_LANGMAP
        LANGMAP_ADJUST(regname, TRUE);
- #endif
      }
      --no_mapping;
  
--- 7712,7718 ----
*** ../vim-7.2.108/src/macros.h Wed Aug 15 20:41:07 2007
--- src/macros.h        Sat Feb 21 19:55:38 2009
***************
*** 127,141 ****
  #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.
   * Don't apply 'langmap' if the character comes from the Stuff buffer.
   * The do-while is just to ignore a ';' after the macro.
   */
! # define LANGMAP_ADJUST(c, condition) do { \
!       if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
!           c = langmap_mapchar[c]; \
      } while (0)
  #endif
  
  /*
--- 127,157 ----
  #ifdef FEAT_LANGMAP
  /*
   * Adjust chars in a language according to 'langmap' option.
!  * NOTE that there is no noticeable overhead if 'langmap' is not set.
!  * When set the overhead for characters < 256 is small.
   * 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) \
!       { \
!           if ((c) < 256) \
!               c = langmap_mapchar[c]; \
!           else \
!               c = langmap_adjust_mb(c); \
!       } \
      } 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
+ #else
+ # define LANGMAP_ADJUST(c, condition) /* nop */
  #endif
  
  /*
*** ../vim-7.2.108/src/normal.c Wed Feb  4 11:45:28 2009
--- src/normal.c        Sat Feb 21 19:55:17 2009
***************
*** 651,660 ****
       * Get the command character from the user.
       */
      c = safe_vgetc();
- 
- #ifdef FEAT_LANGMAP
      LANGMAP_ADJUST(c, TRUE);
- #endif
  
  #ifdef FEAT_VISUAL
      /*
--- 651,657 ----
***************
*** 744,752 ****
            }
            ++no_zero_mapping;          /* don't map zero here */
            c = plain_vgetc();
- #ifdef FEAT_LANGMAP
            LANGMAP_ADJUST(c, TRUE);
- #endif
            --no_zero_mapping;
            if (ctrl_w)
            {
--- 741,747 ----
***************
*** 769,777 ****
            ++no_mapping;
            ++allow_keys;               /* no mapping for nchar, but keys */
            c = plain_vgetc();          /* get next character */
- #ifdef FEAT_LANGMAP
            LANGMAP_ADJUST(c, TRUE);
- #endif
            --no_mapping;
            --allow_keys;
  #ifdef FEAT_CMDL_INFO
--- 764,770 ----
***************
*** 959,967 ****
             * "gr", "g'" and "g`".
             */
            ca.nchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
            LANGMAP_ADJUST(ca.nchar, TRUE);
- #endif
  #ifdef FEAT_CMDL_INFO
            need_flushbuf |= add_to_showcmd(ca.nchar);
  #endif
--- 952,958 ----
***************
*** 1062,1071 ****
                }
  #endif
  
- #ifdef FEAT_LANGMAP
                /* adjust chars > 127, except after "tTfFr" commands */
                LANGMAP_ADJUST(*cp, !lang);
- #endif
  #ifdef FEAT_RIGHTLEFT
                /* adjust Hebrew mapped char */
                if (p_hkmap && lang && KeyTyped)
--- 1053,1060 ----
***************
*** 4630,4638 ****
            ++no_mapping;
            ++allow_keys;   /* no mapping for nchar, but allow key codes */
            nchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
            LANGMAP_ADJUST(nchar, TRUE);
- #endif
            --no_mapping;
            --allow_keys;
  #ifdef FEAT_CMDL_INFO
--- 4619,4625 ----
***************
*** 4988,4996 ****
                ++no_mapping;
                ++allow_keys;   /* no mapping for nchar, but allow key codes */
                nchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
                LANGMAP_ADJUST(nchar, TRUE);
- #endif
                --no_mapping;
                --allow_keys;
  #ifdef FEAT_CMDL_INFO
--- 4975,4981 ----
*** ../vim-7.2.108/src/option.c Wed Feb 11 22:47:32 2009
--- src/option.c        Sat Feb 21 19:46:13 2009
***************
*** 10153,10177 ****
  
  #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.
   */
  
      static void
  langmap_init()
  {
      int i;
  
!     for (i = 0; i < 256; i++)         /* we init with a-one-to one map */
!       langmap_mapchar[i] = i;
  }
  
  /*
--- 10153,10262 ----
  
  #ifdef FEAT_LANGMAP
  /*
!  * 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++)
!       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,10191 ****
      char_u  *p2;
      int           from, to;
  
!     langmap_init();                       /* back to one-to-one map first */
  
      for (p = p_langmap; p[0] != NUL; )
      {
--- 10270,10279 ----
      char_u  *p2;
      int           from, to;
  
! #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,10241 ****
                                                             transchar(from));
                return;
            }
!           langmap_mapchar[from & 255] = to;
  
            /* Advance to next pair */
            mb_ptr_adv(p);
--- 10323,10335 ----
                                                             transchar(from));
                return;
            }
! 
! #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);
*** ../vim-7.2.108/src/proto/option.pro Sat May  5 19:28:04 2007
--- src/proto/option.pro        Wed Feb 11 21:21:05 2009
***************
*** 44,49 ****
--- 44,50 ----
  void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int 
opt_flags));
  int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, 
char_u ***file));
  int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
+ int langmap_adjust_mb __ARGS((int c));
  int has_format_option __ARGS((int x));
  int shortmess __ARGS((int x));
  void vimrc_found __ARGS((char_u *fname, char_u *envname));
*** ../vim-7.2.108/src/window.c Fri Nov 28 21:26:50 2008
--- src/window.c        Sat Feb 21 19:55:25 2009
***************
*** 594,602 ****
                ++allow_keys;   /* no mapping for xchar, but allow key codes */
                if (xchar == NUL)
                    xchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
                LANGMAP_ADJUST(xchar, TRUE);
- #endif
                --no_mapping;
                --allow_keys;
  #ifdef FEAT_CMDL_INFO
--- 594,600 ----
*** ../vim-7.2.108/src/version.c        Wed Feb 11 22:47:32 2009
--- src/version.c       Sat Feb 21 19:34:28 2009
***************
*** 678,679 ****
--- 678,681 ----
  {   /* Add new patch number below this line */
+ /**/
+     109,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
99. The hum of a cooling fan and the click of keys is comforting to you.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui