-*map.txt* For Vim version 7.0aa. Last change: 2006 Mar 06
+*map.txt* For Vim version 7.0aa. Last change: 2006 Mar 10
VIM REFERENCE MANUAL by Bram Moolenaar
1.2 SPECIAL ARGUMENTS *:map-arguments*
+"<buffer>", "<silent>", "<script>", "<expr>" and "<unique>" can be used in any
+order. They must appear right after the command, before any other arguments.
+
*:map-local* *:map-<buffer>* *E224* *E225*
If the first argument to one of these commands is "<buffer>" it will apply to
mappings locally to the current buffer only. Example: >
If you want to map a key and then have it do what it was originally mapped to,
have a look at |maparg()|.
-"<buffer>", "<silent>", "<script>" and "<unique>" can be used in any order.
-They must appear right after the command, before any other arguments.
+ *:map-<expr>* *:map-expression*
+If the first argument to one of these commands is "<expr>" and it is used to
+define a new mapping or abbreviation, the argument is an expression. The
+expression is evaluated to obtain the {rhs} that is used. Example: >
+ :inoremap <expr> . InsertDot()
+The result of the InsertDot() function will be inserted. It could check the
+text before the cursor and start omni completion when some condition is met.
+
+Be very careful about side effects! The expression is evaluated while
+obtaining characters, if you change buffer text, move the cursor, edit another
+file, etc. you may very well make command disfunctional.
+
+Here is an example that inserts a list number that increases: >
+ let counter = 0
+ inoremap <expr> <C-L> ListItem()
+ inoremap <expr> <C-R> ListReset()
+
+ func ListItem()
+ let g:counter += 1
+ return g:counter . '. '
+ endfunc
+
+ func ListReset()
+ let g:counter = 0
+ return ''
+ endfunc
+
+CTRL-L inserts the next number, CTRL-E resets the count. CTRL-E returns an
+empty string, so that nothing is inserted.
1.3 MAPPING AND MODES *:map-modes*
" These commands create the option window.
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2006 Mar 05
+" Last Change: 2006 Mar 10
" If there already is an option window, jump to that one.
if bufwinnr("option-window") > 0
call <SID>OptionG("ccv", &ccv)
call append("$", "delcombine\tDelete combining (composing) characters on their own")
call <SID>BinOptionG("deco", &deco)
+ call append("$", "maxcombine\tMaximum number of combining (composing) characters displayed")
+ call <SID>OptionG("mco", &mco)
if has("xim") && has("gui_gtk")
call append("$", "imactivatekey\tkey that activates the X input method")
call <SID>OptionG("imak", &imak)
int local_State;
int mlen;
int max_mlen;
-#ifdef FEAT_CMDL_INFO
int i;
+#ifdef FEAT_CMDL_INFO
int new_wcol, new_wrow;
#endif
#ifdef FEAT_GUI
}
#endif
+#ifdef FEAT_EVAL
+ /*
+ * Handle ":map <expr>": evaluate the {rhs} as an
+ * expression.
+ */
+ if (mp->m_expr)
+ s = eval_to_string(mp->m_str, NULL, FALSE);
+ else
+#endif
+ s = mp->m_str;
+
/*
* Insert the 'to' part in the typebuf.tb_buf.
* If 'from' field is the same as the start of the
* If m_noremap is set, don't remap the whole 'to'
* part.
*/
- if (ins_typebuf(mp->m_str,
- mp->m_noremap != REMAP_YES
+ if (s == NULL)
+ i = FAIL;
+ else
+ {
+ i = ins_typebuf(s,
+ mp->m_noremap != REMAP_YES
? mp->m_noremap
- : STRNCMP(mp->m_str, mp->m_keys,
+ : STRNCMP(s, mp->m_keys,
(size_t)keylen) != 0
? REMAP_YES : REMAP_SKIP,
- 0, TRUE, cmd_silent || mp->m_silent) == FAIL)
+ 0, TRUE, cmd_silent || mp->m_silent);
+#ifdef FEAT_EVAL
+ if (mp->m_expr)
+ vim_free(s);
+#endif
+ }
+ if (i == FAIL)
{
c = -1;
break;
mapblock_T **map_table;
int unique = FALSE;
int silent = FALSE;
+#ifdef FEAT_EVAL
+ int expr = FALSE;
+#endif
int noremap;
keys = arg;
else
noremap = REMAP_YES;
- /* Accept <buffer>, <silent>, <script> and <unique> in any order. */
+ /* Accept <buffer>, <silent>, <expr> <script> and <unique> in any order. */
for (;;)
{
#ifdef FEAT_LOCALMAP
noremap = REMAP_SCRIPT;
continue;
}
+
+ /*
+ * Check for "<expr>": {rhs} is an expression.
+ */
+ if (STRNCMP(keys, "<expr>", 6) == 0)
+ {
+ keys = skipwhite(keys + 6);
+ expr = TRUE;
+ continue;
+ }
#endif
/*
* Check for "<unique>": don't overwrite an existing mapping.
mp->m_silent = silent;
mp->m_mode = mode;
#ifdef FEAT_EVAL
+ mp->m_expr = expr;
mp->m_script_ID = current_SID;
#endif
did_it = TRUE;
mp->m_silent = silent;
mp->m_mode = mode;
#ifdef FEAT_EVAL
+ mp->m_expr = expr;
mp->m_script_ID = current_SID;
#endif
arg = skipwhite(arg + 8);
continue;
}
+#ifdef FEAT_EVAL
if (STRNCMP(arg, "<script>", 8) == 0)
{
arg = skipwhite(arg + 8);
continue;
}
+ if (STRNCMP(arg, "<expr>", 6) == 0)
+ {
+ arg = skipwhite(arg + 6);
+ continue;
+ }
+#endif
break;
}
xp->xp_pattern = arg;
{
count = 0;
- for (i = 0; i < 4; ++i)
+ for (i = 0; i < 5; ++i)
{
if (i == 0)
p = (char_u *)"<silent>";
#ifdef FEAT_EVAL
else if (i == 2)
p = (char_u *)"<script>";
+ else if (i == 3)
+ p = (char_u *)"<expr>";
#endif
#ifdef FEAT_LOCALMAP
- else if (i == 3 && !expand_buffer)
+ else if (i == 4 && !expand_buffer)
p = (char_u *)"<buffer>";
#endif
else
int len;
int scol; /* starting column of the abbr. */
int j;
+ char_u *s;
#ifdef FEAT_MBYTE
char_u tb[MB_MAXBYTES + 4];
#else
/* insert the last typed char */
(void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
}
+#ifdef FEAT_EVAL
+ if (mp->m_expr)
+ s = eval_to_string(mp->m_str, NULL, FALSE);
+ else
+#endif
+ s = mp->m_str;
+ if (s != NULL)
+ {
/* insert the to string */
- (void)ins_typebuf(mp->m_str, mp->m_noremap, 0, TRUE, mp->m_silent);
+ (void)ins_typebuf(s, mp->m_noremap, 0, TRUE, mp->m_silent);
/* no abbrev. for these chars */
- typebuf.tb_no_abbr_cnt += (int)STRLEN(mp->m_str) + j + 1;
+ typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
+#ifdef FEAT_EVAL
+ if (mp->m_expr)
+ vim_free(s);
+#endif
+ }
tb[0] = Ctrl_H;
tb[1] = NUL;
return FAIL;
if (mp->m_silent && fputs(" <silent>", fd) < 0)
return FAIL;
+#ifdef FEAT_EVAL
+ if (mp->m_noremap == REMAP_SCRIPT
+ && fputs("<script>", fd) < 0)
+ return FAIL;
+ if (mp->m_expr && fputs(" <expr>", fd) < 0)
+ return FAIL;
+#endif
if ( putc(' ', fd) < 0
|| put_escstr(fd, mp->m_keys, 0) == FAIL