]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.032 v7.3.032
authorBram Moolenaar <Bram@vim.org>
Wed, 20 Oct 2010 19:23:33 +0000 (21:23 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 20 Oct 2010 19:23:33 +0000 (21:23 +0200)
Problem:    maparg() doesn't return the flags, such as <buffer>, <script>,
            <silent>.  These are needed to save and restore a mapping.
Solution:   Improve maparg(). (also by Christian Brabandt)

runtime/doc/eval.txt
src/eval.c
src/getchar.c
src/gui_w48.c
src/message.c
src/proto/getchar.pro
src/proto/message.pro
src/structs.h
src/testdir/test75.in [new file with mode: 0644]
src/testdir/test75.ok [new file with mode: 0644]
src/version.c

index d37fe2ab334c935e0ef7ceb042e891a6f6dca9d7..d1a1ba3f21485601704f8f533487b95006ed1889 100644 (file)
@@ -1827,7 +1827,7 @@ localtime()                       Number  current time
 log( {expr})                   Float   natural logarithm (base e) of {expr}
 log10( {expr})                 Float   logarithm of Float {expr} to base 10
 map( {expr}, {string})         List/Dict  change each item in {expr} to {expr}
-maparg( {name}[, {mode} [, {abbr}]])
+maparg( {name}[, {mode} [, {abbr} [, {dict}]]])
                                String  rhs of mapping {name} in mode {mode}
 mapcheck( {name}[, {mode} [, {abbr}]])
                                String  check for mappings matching {name}
@@ -3972,23 +3972,51 @@ map({expr}, {string})                                   *map()*
                further items in {expr} are processed.
 
 
-maparg({name}[, {mode} [, {abbr}]])                    *maparg()*
-               Return the rhs of mapping {name} in mode {mode}.  When there
-               is no mapping for {name}, an empty String is returned.
+maparg({name}[, {mode} [, {abbr} [, {dict}]]])                 *maparg()*
+               When {dict} is omitted or zero: Return the rhs of mapping
+               {name} in mode {mode}.  The returned String has special
+               characters translated like in the output of the ":map" command
+               listing.
+               
+               When there is no mapping for {name}, an empty String is
+               returned.
+
+               The {name} can have special key names, like in the ":map"
+               command.
+
                {mode} can be one of these strings:
                        "n"     Normal
-                       "v"     Visual
+                       "v"     Visual (including Select)
                        "o"     Operator-pending
                        "i"     Insert
                        "c"     Cmd-line
+                       "s"     Select
+                       "x"     Visual
                        "l"     langmap |language-mapping|
                        ""      Normal, Visual and Operator-pending
                When {mode} is omitted, the modes for "" are used.
+
                When {abbr} is there and it is non-zero use abbreviations
                instead of mappings.
-               The {name} can have special key names, like in the ":map"
-               command.  The returned String has special characters
-               translated like in the output of the ":map" command listing.
+
+               When {dict} is there and it is non-zero return a dictionary
+               containing all the information of the mapping with the
+               following items:
+                 "lhs"      The {lhs} of the mapping.
+                 "rhs"      The {rhs} of the mapping as typed.
+                 "silent"   1 for a |:map-silent| mapping, else 0.
+                 "noremap"  1 if the {rhs} of the mapping is remappable.
+                 "expr"     1 for an expression mapping (|:map-<expr>|).
+                 "buffer"   1 for a buffer local mapping (|:map-local|).
+                 "mode"     Modes for which the mapping is defined. In
+                            addition to the modes mentioned above, these
+                            characters will be used:
+                            " "     Normal, Visual and Operator-pending
+                            "!"     Insert and Commandline mode
+                                    (|mapmpde-ic|)
+                 "sid"      the Script local ID, used for <sid> mappings
+                            (|<SID>|)
+
                The mappings local to the current buffer are checked first,
                then the global mappings.
                This function can be used to map a key even when it's already
index 1216dc67298b094d6238815ce8f09f07003aa503..d7cee74350841711eb5e2658beed566b2e4ff019 100644 (file)
@@ -7804,7 +7804,7 @@ static struct fst
     {"log10",          1, 1, f_log10},
 #endif
     {"map",            2, 2, f_map},
-    {"maparg",         1, 3, f_maparg},
+    {"maparg",         1, 4, f_maparg},
     {"mapcheck",       1, 3, f_mapcheck},
     {"match",          2, 4, f_match},
     {"matchadd",       2, 4, f_matchadd},
@@ -13292,8 +13292,10 @@ get_maparg(argvars, rettv, exact)
     char_u     *keys_buf = NULL;
     char_u     *rhs;
     int                mode;
-    garray_T   ga;
     int                abbr = FALSE;
+    int         get_dict = FALSE;
+    mapblock_T *mp;
+    int                buffer_local;
 
     /* return empty string for failure */
     rettv->v_type = VAR_STRING;
@@ -13307,7 +13309,11 @@ get_maparg(argvars, rettv, exact)
     {
        which = get_tv_string_buf_chk(&argvars[1], buf);
        if (argvars[2].v_type != VAR_UNKNOWN)
+       {
            abbr = get_tv_number(&argvars[2]);
+           if (argvars[3].v_type != VAR_UNKNOWN)
+               get_dict = get_tv_number(&argvars[3]);
+       }
     }
     else
        which = (char_u *)"";
@@ -13317,19 +13323,34 @@ get_maparg(argvars, rettv, exact)
     mode = get_map_mode(&which, 0);
 
     keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE);
-    rhs = check_map(keys, mode, exact, FALSE, abbr);
+    rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local);
     vim_free(keys_buf);
-    if (rhs != NULL)
+
+    if (!get_dict)
     {
-       ga_init(&ga);
-       ga.ga_itemsize = 1;
-       ga.ga_growsize = 40;
+       /* Return a string. */
+       if (rhs != NULL)
+           rettv->vval.v_string = str2special_save(rhs, FALSE);
 
-       while (*rhs != NUL)
-           ga_concat(&ga, str2special(&rhs, FALSE));
+    }
+    else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL)
+    {
+       /* Return a dictionary. */
+       char_u      *lhs = str2special_save(mp->m_keys, TRUE);
+       char_u      *mapmode = map_mode_to_chars(mp->m_mode);
+       dict_T      *dict = rettv->vval.v_dict;
 
-       ga_append(&ga, NUL);
-       rettv->vval.v_string = (char_u *)ga.ga_data;
+       dict_add_nr_str(dict, "lhs",     0L, lhs);
+       dict_add_nr_str(dict, "rhs",     0L, mp->m_orig_str);
+       dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L , NULL);
+       dict_add_nr_str(dict, "expr",    mp->m_expr    ? 1L : 0L, NULL);
+       dict_add_nr_str(dict, "silent",  mp->m_silent  ? 1L : 0L, NULL);
+       dict_add_nr_str(dict, "sid",     (long)mp->m_script_ID, NULL);
+       dict_add_nr_str(dict, "buffer",  (long)buffer_local, NULL);
+       dict_add_nr_str(dict, "mode",    0L, mapmode);
+
+       vim_free(lhs);
+       vim_free(mapmode);
     }
 }
 
index c892b46454087fe94c1e935c0490389ae77b2adf..8462517cdb6b87b7cc7d80f874c57ccde80ccf3e 100644 (file)
@@ -3168,6 +3168,7 @@ do_map(maptype, arg, mode, abbrev)
     int                expr = FALSE;
 #endif
     int                noremap;
+    char_u      *orig_rhs;
 
     keys = arg;
     map_table = maphash;
@@ -3266,6 +3267,7 @@ do_map(maptype, arg, mode, abbrev)
     }
     if (*p != NUL)
        *p++ = NUL;
+
     p = skipwhite(p);
     rhs = p;
     hasarg = (*rhs != NUL);
@@ -3290,6 +3292,7 @@ do_map(maptype, arg, mode, abbrev)
        keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, special);
     if (hasarg)
     {
+       orig_rhs = rhs;
        if (STRICMP(rhs, "<nop>") == 0)     /* "<Nop>" means nothing */
            rhs = (char_u *)"";
        else
@@ -3298,7 +3301,7 @@ do_map(maptype, arg, mode, abbrev)
 
 #ifdef FEAT_FKMAP
     /*
-     * when in right-to-left mode and alternate keymap option set,
+     * When in right-to-left mode and alternate keymap option set,
      * reverse the character flow in the rhs in Farsi.
      */
     if (p_altkeymap && curwin->w_p_rl)
@@ -3556,6 +3559,8 @@ do_map(maptype, arg, mode, abbrev)
                                }
                                vim_free(mp->m_str);
                                mp->m_str = newstr;
+                               vim_free(mp->m_orig_str);
+                               mp->m_orig_str = vim_strsave(orig_rhs);
                                mp->m_noremap = noremap;
                                mp->m_silent = silent;
                                mp->m_mode = mode;
@@ -3633,10 +3638,12 @@ do_map(maptype, arg, mode, abbrev)
 
     mp->m_keys = vim_strsave(keys);
     mp->m_str = vim_strsave(rhs);
+    mp->m_orig_str = vim_strsave(orig_rhs);
     if (mp->m_keys == NULL || mp->m_str == NULL)
     {
        vim_free(mp->m_keys);
        vim_free(mp->m_str);
+       vim_free(mp->m_orig_str);
        vim_free(mp);
        retval = 4;     /* no mem */
        goto theend;
@@ -3682,6 +3689,7 @@ map_free(mpp)
     mp = *mpp;
     vim_free(mp->m_keys);
     vim_free(mp->m_str);
+    vim_free(mp->m_orig_str);
     *mpp = mp->m_next;
     vim_free(mp);
 }
@@ -3851,12 +3859,57 @@ map_clear_int(buf, mode, local, abbr)
     }
 }
 
+/*
+ * Return characters to represent the map mode in an allocated string.
+ * Returns NULL when out of memory.
+ */
+    char_u *
+map_mode_to_chars(mode)
+    int mode;
+{
+    garray_T    mapmode;
+
+    ga_init2(&mapmode, 1, 7);
+
+    if ((mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
+       ga_append(&mapmode, '!');                       /* :map! */
+    else if (mode & INSERT)
+       ga_append(&mapmode, 'i');                       /* :imap */
+    else if (mode & LANGMAP)
+       ga_append(&mapmode, 'l');                       /* :lmap */
+    else if (mode & CMDLINE)
+       ga_append(&mapmode, 'c');                       /* :cmap */
+    else if ((mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
+                                == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
+       ga_append(&mapmode, ' ');                       /* :map */
+    else
+    {
+       if (mode & NORMAL)
+           ga_append(&mapmode, 'n');                   /* :nmap */
+       if (mode & OP_PENDING)
+           ga_append(&mapmode, 'o');                   /* :omap */
+       if ((mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
+           ga_append(&mapmode, 'v');                   /* :vmap */
+       else
+       {
+           if (mode & VISUAL)
+               ga_append(&mapmode, 'x');               /* :xmap */
+           if (mode & SELECTMODE)
+               ga_append(&mapmode, 's');               /* :smap */
+       }
+    }
+
+    ga_append(&mapmode, NUL);
+    return (char_u *)mapmode.ga_data;
+}
+
     static void
 showmap(mp, local)
     mapblock_T *mp;
     int                local;      /* TRUE for buffer-local map */
 {
-    int len = 1;
+    int                len = 1;
+    char_u     *mapchars;
 
     if (msg_didout || msg_silent != 0)
     {
@@ -3864,49 +3917,15 @@ showmap(mp, local)
        if (got_int)        /* 'q' typed at MORE prompt */
            return;
     }
-    if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
-       msg_putchar('!');                       /* :map! */
-    else if (mp->m_mode & INSERT)
-       msg_putchar('i');                       /* :imap */
-    else if (mp->m_mode & LANGMAP)
-       msg_putchar('l');                       /* :lmap */
-    else if (mp->m_mode & CMDLINE)
-       msg_putchar('c');                       /* :cmap */
-    else if ((mp->m_mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
-                                == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
-       msg_putchar(' ');                       /* :map */
-    else
+
+    mapchars = map_mode_to_chars(mp->m_mode);
+    if (mapchars != NULL)
     {
-       len = 0;
-       if (mp->m_mode & NORMAL)
-       {
-           msg_putchar('n');           /* :nmap */
-           ++len;
-       }
-       if (mp->m_mode & OP_PENDING)
-       {
-           msg_putchar('o');           /* :omap */
-           ++len;
-       }
-       if ((mp->m_mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
-       {
-           msg_putchar('v');           /* :vmap */
-           ++len;
-       }
-       else
-       {
-           if (mp->m_mode & VISUAL)
-           {
-               msg_putchar('x');               /* :xmap */
-               ++len;
-           }
-           if (mp->m_mode & SELECTMODE)
-           {
-               msg_putchar('s');               /* :smap */
-               ++len;
-           }
-       }
+       msg_puts(mapchars);
+       len = STRLEN(mapchars);
+       vim_free(mapchars);
     }
+
     while (++len <= 3)
        msg_putchar(' ');
 
@@ -3931,8 +3950,7 @@ showmap(mp, local)
        msg_putchar(' ');
 
     /* Use FALSE below if we only want things like <Up> to show up as such on
-     * the rhs, and not M-x etc, TRUE gets both -- webb
-     */
+     * the rhs, and not M-x etc, TRUE gets both -- webb */
     if (*mp->m_str == NUL)
        msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
     else
@@ -4995,19 +5013,21 @@ check_map_keycodes()
     sourcing_name = save_name;
 }
 
-#ifdef FEAT_EVAL
+#if defined(FEAT_EVAL) || defined(PROTO)
 /*
- * Check the string "keys" against the lhs of all mappings
- * Return pointer to rhs of mapping (mapblock->m_str)
- * NULL otherwise
+ * Check the string "keys" against the lhs of all mappings.
+ * Return pointer to rhs of mapping (mapblock->m_str).
+ * NULL when no mapping found.
  */
     char_u *
-check_map(keys, mode, exact, ign_mod, abbr)
+check_map(keys, mode, exact, ign_mod, abbr, mp_ptr, local_ptr)
     char_u     *keys;
     int                mode;
     int                exact;          /* require exact match */
     int                ign_mod;        /* ignore preceding modifier */
     int                abbr;           /* do abbreviations */
+    mapblock_T **mp_ptr;       /* return: pointer to mapblock or NULL */
+    int                *local_ptr;     /* return: buffer-local mapping or NULL */
 {
     int                hash;
     int                len, minlen;
@@ -5062,7 +5082,13 @@ check_map(keys, mode, exact, ign_mod, abbr)
                            minlen = mp->m_keylen - 3;
                    }
                    if (STRNCMP(s, keys, minlen) == 0)
+                   {
+                       if (mp_ptr != NULL)
+                           *mp_ptr = mp;
+                       if (local_ptr != NULL)
+                           *local_ptr = local;
                        return mp->m_str;
+                   }
                }
            }
        }
index 80b75ff384c11793237ab5d6020937e181c12ee6..445104dae0dee662e4bbb314542f6c2fb4ac6251 100644 (file)
@@ -1810,7 +1810,8 @@ process_message(void)
                 * mapped we want to use the mapping instead. */
                if (vk == VK_F10
                        && gui.menu_is_active
-                       && check_map(k10, State, FALSE, TRUE, FALSE) == NULL)
+                       && check_map(k10, State, FALSE, TRUE, FALSE,
+                                                         NULL, NULL) == NULL)
                    break;
 #endif
                if (GetKeyState(VK_SHIFT) & 0x8000)
@@ -1924,7 +1925,8 @@ process_message(void)
     /* Check for <F10>: Default effect is to select the menu.  When <F10> is
      * mapped we need to stop it here to avoid strange effects (e.g., for the
      * key-up event) */
-    if (vk != VK_F10 || check_map(k10, State, FALSE, TRUE, FALSE) == NULL)
+    if (vk != VK_F10 || check_map(k10, State, FALSE, TRUE, FALSE,
+                                                         NULL, NULL) == NULL)
 #endif
        DispatchMessage(&msg);
 }
index c33b173b89bba6088362ed31d5ece4b80dbcf11d..ac81948f2c087ffe86300603dda87f97eb887c04 100644 (file)
@@ -1477,6 +1477,27 @@ msg_outtrans_special(strstart, from)
     return retval;
 }
 
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return the lhs or rhs of a mapping, with the key codes turned into printable
+ * strings, in an allocated string.
+ */
+    char_u *
+str2special_save(str, is_lhs)
+    char_u  *str;
+    int            is_lhs;  /* TRUE for lhs, FALSE for rhs */
+{
+    garray_T   ga;
+    char_u     *p = str;
+
+    ga_init2(&ga, 1, 40);
+    while (*p != NUL)
+       ga_concat(&ga, str2special(&p, is_lhs));
+    ga_append(&ga, NUL);
+    return (char_u *)ga.ga_data;
+}
+#endif
+
 /*
  * Return the printable string for the key codes at "*sp".
  * Used for translating the lhs or rhs of a mapping to printable chars.
index 06081c321145673aeb09bce5fd52e8bab8aa0d7e..a304bafa53d70d4201a1cf52bde16daa23d949ab 100644 (file)
@@ -51,6 +51,7 @@ int do_map __ARGS((int maptype, char_u *arg, int mode, int abbrev));
 int get_map_mode __ARGS((char_u **cmdp, int forceit));
 void map_clear __ARGS((char_u *cmdp, char_u *arg, int forceit, int abbr));
 void map_clear_int __ARGS((buf_T *buf, int mode, int local, int abbr));
+char_u *map_mode_to_chars __ARGS((int mode));
 int map_to_exists __ARGS((char_u *str, char_u *modechars, int abbr));
 int map_to_exists_mode __ARGS((char_u *rhs, int mode, int abbr));
 char_u *set_context_in_map_cmd __ARGS((expand_T *xp, char_u *cmd, char_u *arg, int forceit, int isabbrev, int isunmap, cmdidx_T cmdidx));
@@ -61,7 +62,7 @@ void vim_unescape_csi __ARGS((char_u *p));
 int makemap __ARGS((FILE *fd, buf_T *buf));
 int put_escstr __ARGS((FILE *fd, char_u *strstart, int what));
 void check_map_keycodes __ARGS((void));
-char_u *check_map __ARGS((char_u *keys, int mode, int exact, int ign_mod, int abbr));
+char_u *check_map __ARGS((char_u *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr, int *local_ptr));
 void init_mappings __ARGS((void));
 void add_map __ARGS((char_u *map, int mode));
 /* vim: set ft=c : */
index 09b9152b755b11159634b7cda2028becf1a6bfb3..a752ddcf56b759b85dc9cf3bba7482ceeb1a24b4 100644 (file)
@@ -33,6 +33,7 @@ char_u *msg_outtrans_one __ARGS((char_u *p, int attr));
 int msg_outtrans_len_attr __ARGS((char_u *msgstr, int len, int attr));
 void msg_make __ARGS((char_u *arg));
 int msg_outtrans_special __ARGS((char_u *strstart, int from));
+char_u *str2special_save __ARGS((char_u *str, int is_lhs));
 char_u *str2special __ARGS((char_u **sp, int from));
 void str2specialbuf __ARGS((char_u *sp, char_u *buf, int len));
 void msg_prt_line __ARGS((char_u *s, int list));
index 884d6a9fe56caa5a7ec8f46e1f8cf98e06fa0d32..aa93aaedcd835ec7fb0b1b82882ece2850e933f6 100644 (file)
@@ -979,9 +979,10 @@ typedef struct mapblock mapblock_T;
 struct mapblock
 {
     mapblock_T *m_next;        /* next mapblock in list */
-    char_u     *m_keys;        /* mapped from */
+    char_u     *m_keys;        /* mapped from, lhs */
     int                m_keylen;       /* strlen(m_keys) */
-    char_u     *m_str;         /* mapped to */
+    char_u     *m_str;         /* mapped to, rhs */
+    char_u     *m_orig_str;    /* rhs as entered by the user */
     int                m_mode;         /* valid mode */
     int                m_noremap;      /* if non-zero no re-mapping for m_str */
     char       m_silent;       /* <silent> used, don't echo commands */
diff --git a/src/testdir/test75.in b/src/testdir/test75.in
new file mode 100644 (file)
index 0000000..2de7a08
--- /dev/null
@@ -0,0 +1,16 @@
+" Tests for functions.
+
+STARTTEST
+:so small.vim
+:" Test maparg() with a string result
+:map foo<C-V> is<F4>foo
+:vnoremap <script> <buffer> <expr> <silent> bar isbar
+:call append('$', maparg('foo<C-V>'))
+:call append('$', string(maparg('foo<C-V>', '', 0, 1)))
+:call append('$', string(maparg('bar', '', 0, 1)))
+:"
+:/^eof/+1,$w! test.out
+:qa!
+ENDTEST
+
+eof
diff --git a/src/testdir/test75.ok b/src/testdir/test75.ok
new file mode 100644 (file)
index 0000000..7916563
--- /dev/null
@@ -0,0 +1,3 @@
+is<F4>foo
+{'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
+{'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
index e5164d362051f7804e42c51f59e4d5a08cfee55e..d8e9a519fe3ae434466014ab44da3575ecaa94a4 100644 (file)
@@ -714,6 +714,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    32,
 /**/
     31,
 /**/