To: vim-dev@vim.org Subject: Patch 6.2.442 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.442 Problem: Cannot manipulate the command line from a function. Solution: Add getcmdline(), getcmdpos() and setcmdpos() functions and the CTRL-\ e command. Files: runtime/doc/cmdline.txt, runtime/doc/eval.txt, src/eval.c src/ex_getln.c, src/ops.c, src/proto/ex_getln.pro, src/proto/ops.pro *** ../vim-6.2.441/runtime/doc/cmdline.txt Sun Jun 1 12:20:31 2003 --- runtime/doc/cmdline.txt Wed Mar 31 19:20:55 2004 *************** *** 1,4 **** ! *cmdline.txt* For Vim version 6.2. Last change: 2003 May 16 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *cmdline.txt* For Vim version 6.2. Last change: 2004 Mar 31 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 175,180 **** --- 177,201 ---- "CTRL-R a" will insert "xz" while "CTRL-R CTRL-R a" will insert "xy^Hz". + CTRL-\ e {expr} *c_CTRL-\_e* + Evaluate {expr} and replace the whole command line with the + result. You will be prompted for the expression, type + to finish it. It's most useful in mappings though. See + |expression|. + See |c_CTRL-R_=| for inserting the result of an expression. + Useful functions are |getcmdline()| and |getcmdpos()|. + The cursor position is unchanged, except when the cursor was + at the end of the line, then it stays at the end. + |setcmdpos()| can be used to set the cursor position. + Example: > + :cmap eAppendSome() + :func AppendSome() + :let cmd = getcmdline() . " Some()" + :" place the cursor on the ) + :call setcmdpos(strlen(cmd)) + :return cmd + :endfunc + < *c_CTRL-Y* CTRL-Y When there is a modeless selection, copy the selection into the clipboard. |modeless-selection| *** ../vim-6.2.441/runtime/doc/eval.txt Thu Feb 19 15:31:20 2004 --- runtime/doc/eval.txt Wed Mar 31 19:18:08 2004 *************** *** 1,4 **** ! *eval.txt* For Vim version 6.2. Last change: 2004 Feb 15 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *eval.txt* For Vim version 6.2. Last change: 2004 Mar 31 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 826,831 **** --- 827,834 ---- getchar( [expr]) Number get one character from the user getcharmod( ) Number modifiers for the last typed character getbufvar( {expr}, {varname}) variable {varname} in buffer {expr} + getcmdline() String return the current command-line + getcmdpos() Number return cursor position in command-line getcwd() String the current working directory getfsize( {fname}) Number size in bytes of file getftime( {fname}) Number last modification time of file *************** *** 889,894 **** --- 892,898 ---- Number send reply string serverlist() String get a list of available servers setbufvar( {expr}, {varname}, {val}) set {varname} in buffer {expr} to {val} + setcmdpos( {pos}) Number set cursor position in command-line setline( {lnum}, {line}) Number set line {lnum} to {line} setreg( {n}, {v}[, {opt}]) Number set register to value and type setwinvar( {nr}, {varname}, {val}) set {varname} in window {nr} to {val} *************** *** 1485,1490 **** --- 1491,1511 ---- :let bufmodified = getbufvar(1, "&mod") :echo "todo myvar = " . getbufvar("todo", "myvar") < + getcmdline() *getcmdline()* + Return the current command-line. Only works when the command + line is being edited, thus requires use of |c_CTRL-\_e| or + |c_CTRL-R_=|. + Example: > + :cmap eescape(getcmdline(), ' \') + < Also see |getcmdpos()| and |setcmdpos()|. + + getcmdpos({pos}) *getcmdpos()* + Return the position of the cursor in the command line as a + byte count. The first column is 1. + Only works when editing the command line, thus requires use of + |c_CTRL-\_e| or |c_CTRL-R_=|. Returns 0 otherwise. + Also see |setcmdpos()| and |getcmdline()|. + *getcwd()* getcwd() The result is a String, which is the name of the current working directory. *************** *** 2277,2282 **** --- 2301,2318 ---- :call setbufvar("todo", "myvar", "foobar") < This function is not available in the |sandbox|. + setcmdpos({pos}) *setcmdpos()* + Set the cursor position in the command line to byte position + {pos}. The first position is 1. + Use |getcmdpos()| to obtain the current position. + Only works while editing the command line, thus you must use + |c_CTRL-\_e| or |c_CTRL-R_=|. The position is set after the + command line is set to the expression. + When the number is too big the cursor is put at the end of the + line. A number smaller than one has undefined results. + Returns 0 when successful, 1 when not editing the command + line. + setline({lnum}, {line}) *setline()* Set line {lnum} of the current buffer to {line}. If this succeeds, 0 is returned. If this fails (most likely because *** ../vim-6.2.441/src/eval.c Tue Mar 30 22:17:27 2004 --- src/eval.c Wed Mar 31 20:29:18 2004 *************** *** 286,292 **** static void f_getbufvar __ARGS((VAR argvars, VAR retvar)); static void f_getchar __ARGS((VAR argvars, VAR retvar)); static void f_getcharmod __ARGS((VAR argvars, VAR retvar)); ! static void f_getwinvar __ARGS((VAR argvars, VAR retvar)); static void f_getcwd __ARGS((VAR argvars, VAR retvar)); static void f_getfsize __ARGS((VAR argvars, VAR retvar)); static void f_getftime __ARGS((VAR argvars, VAR retvar)); --- 286,293 ---- static void f_getbufvar __ARGS((VAR argvars, VAR retvar)); static void f_getchar __ARGS((VAR argvars, VAR retvar)); static void f_getcharmod __ARGS((VAR argvars, VAR retvar)); ! static void f_getcmdline __ARGS((VAR argvars, VAR retvar)); ! static void f_getcmdpos __ARGS((VAR argvars, VAR retvar)); static void f_getcwd __ARGS((VAR argvars, VAR retvar)); static void f_getfsize __ARGS((VAR argvars, VAR retvar)); static void f_getftime __ARGS((VAR argvars, VAR retvar)); *************** *** 295,300 **** --- 296,302 ---- static void f_getregtype __ARGS((VAR argvars, VAR retvar)); static void f_getwinposx __ARGS((VAR argvars, VAR retvar)); static void f_getwinposy __ARGS((VAR argvars, VAR retvar)); + static void f_getwinvar __ARGS((VAR argvars, VAR retvar)); static void f_glob __ARGS((VAR argvars, VAR retvar)); static void f_globpath __ARGS((VAR argvars, VAR retvar)); static void f_has __ARGS((VAR argvars, VAR retvar)); *************** *** 333,338 **** --- 335,341 ---- static void f_nr2char __ARGS((VAR argvars, VAR retvar)); static void f_prevnonblank __ARGS((VAR argvars, VAR retvar)); static void f_setbufvar __ARGS((VAR argvars, VAR retvar)); + static void f_setcmdpos __ARGS((VAR argvars, VAR retvar)); static void f_setwinvar __ARGS((VAR argvars, VAR retvar)); static void f_rename __ARGS((VAR argvars, VAR retvar)); static void f_resolve __ARGS((VAR argvars, VAR retvar)); *************** *** 2805,2810 **** --- 2808,2815 ---- {"getbufvar", 2, 2, f_getbufvar}, {"getchar", 0, 1, f_getchar}, {"getcharmod", 0, 0, f_getcharmod}, + {"getcmdline", 0, 0, f_getcmdline}, + {"getcmdpos", 0, 0, f_getcmdpos}, {"getcwd", 0, 0, f_getcwd}, {"getfsize", 1, 1, f_getfsize}, {"getftime", 1, 1, f_getftime}, *************** *** 2863,2868 **** --- 2868,2874 ---- {"server2client", 2, 2, f_server2client}, {"serverlist", 0, 0, f_serverlist}, {"setbufvar", 3, 3, f_setbufvar}, + {"setcmdpos", 1, 1, f_setcmdpos}, {"setline", 2, 2, f_setline}, {"setreg", 2, 3, f_setreg}, {"setwinvar", 3, 3, f_setwinvar}, *************** *** 4318,4323 **** --- 4324,4354 ---- } /* + * "getcmdline()" function + */ + /*ARGSUSED*/ + static void + f_getcmdline(argvars, retvar) + VAR argvars; + VAR retvar; + { + retvar->var_type = VAR_STRING; + retvar->var_val.var_string = get_cmdline_str(); + } + + /* + * "getcmdpos()" function + */ + /*ARGSUSED*/ + static void + f_getcmdpos(argvars, retvar) + VAR argvars; + VAR retvar; + { + retvar->var_val.var_number = get_cmdline_pos() + 1; + } + + /* * "getbufvar()" function */ static void *************** *** 6352,6357 **** --- 6383,6400 ---- } /* + * "setcmdpos()" function + */ + static void + f_setcmdpos(argvars, retvar) + VAR argvars; + VAR retvar; + { + retvar->var_val.var_number = set_cmdline_pos( + (int)get_var_number(&argvars[0]) - 1); + } + + /* * "setline()" function */ static void *************** *** 6376,6381 **** --- 6419,6425 ---- retvar->var_val.var_number = 0; } } + /* * "setreg()" function */ *** ../vim-6.2.441/src/ex_getln.c Tue Mar 30 21:47:08 2004 --- src/ex_getln.c Wed Mar 31 19:19:16 2004 *************** *** 37,42 **** --- 37,45 ---- static int cmd_showtail; /* Only show path tail in lists ? */ + #ifdef FEAT_EVAL + static int new_cmdpos; /* position set by set_cmdline_pos() */ + #endif #ifdef FEAT_CMDHIST typedef struct hist_entry *************** *** 575,585 **** c = safe_vgetc(); --no_mapping; --allow_keys; ! if (c != Ctrl_N && c != Ctrl_G) { vungetc(c); c = Ctrl_BSL; } else { if (c == Ctrl_G && p_im && restart_edit == 0) --- 578,636 ---- c = safe_vgetc(); --no_mapping; --allow_keys; ! if (c != Ctrl_N && c != Ctrl_G && c != 'e') { vungetc(c); c = Ctrl_BSL; } + #ifdef FEAT_EVAL + else if (c == 'e') + { + /* + * Replace the command line with the result of an expression. + * Need to save the current command line, to be able to enter + * a new one... + */ + if (ccline.cmdfirstc != '=') /* can't do this recursively */ + { + struct cmdline_info save_ccline; + char_u *p; + + if (ccline.cmdpos == ccline.cmdlen) + new_cmdpos = 99999; /* keep it at the end */ + else + new_cmdpos = ccline.cmdpos; + save_ccline = ccline; + ccline.cmdbuff = NULL; + ccline.cmdprompt = NULL; + c = get_expr_register(); + ccline = save_ccline; + if (c == '=') + { + p = get_expr_line(); + if (p != NULL && realloc_cmdbuff(STRLEN(p) + 1) == OK) + { + ccline.cmdlen = STRLEN(p); + STRCPY(ccline.cmdbuff, p); + vim_free(p); + + /* Restore the cursor or use the position set with + * set_cmdline_pos(). */ + if (new_cmdpos > ccline.cmdlen) + ccline.cmdpos = ccline.cmdlen; + else + ccline.cmdpos = new_cmdpos; + + KeyTyped = FALSE; /* Don't do p_wc completion. */ + redrawcmd(); + goto cmdline_changed; + } + } + } + beep_flush(); + c = ESC; + } + #endif else { if (c == Ctrl_G && p_im && restart_edit == 0) *************** *** 959,964 **** --- 1010,1016 ---- * Need to save the current command line, to be able to enter * a new one... */ + new_cmdpos = -1; if (c == '=') { struct cmdline_info save_ccline; *************** *** 982,987 **** --- 1034,1049 ---- { cmdline_paste(c, i == Ctrl_R); KeyTyped = FALSE; /* Don't do p_wc completion. */ + #ifdef FEAT_EVAL + if (new_cmdpos >= 0) + { + /* set_cmdline_pos() was used */ + if (new_cmdpos > ccline.cmdlen) + ccline.cmdpos = ccline.cmdlen; + else + ccline.cmdpos = new_cmdpos; + } + #endif } redrawcmd(); goto cmdline_changed; *************** *** 4353,4358 **** --- 4415,4468 ---- return -1; return history[histype][hisidx[histype]].hisnum; + } + + /* + * Get the current command line in allocated memory. + * Only works when the command line is being edited. + * Returns NULL when something is wrong. + */ + char_u * + get_cmdline_str() + { + if (ccline.cmdbuff == NULL || (State & CMDLINE) == 0) + return NULL; + return vim_strnsave(ccline.cmdbuff, ccline.cmdlen); + } + + /* + * Get the current command line position, counted in bytes. + * Zero is the first position. + * Only works when the command line is being edited. + * Returns -1 when something is wrong. + */ + int + get_cmdline_pos() + { + if (ccline.cmdbuff == NULL || (State & CMDLINE) == 0) + return -1; + return ccline.cmdpos; + } + + /* + * Set the command line byte position to "pos". Zero is the first position. + * Only works when the command line is being edited. + * Returns 1 when failed, 0 when OK. + */ + int + set_cmdline_pos(pos) + int pos; + { + if (ccline.cmdbuff == NULL || (State & CMDLINE) == 0) + return 1; + + /* The position is not set directly but after CTRL-\ e or CTRL-R = has + * changed the command line. */ + if (pos < 0) + new_cmdpos = 0; + else + new_cmdpos = pos; + return 0; } /* *** ../vim-6.2.441/src/ops.c Tue Mar 30 21:58:19 2004 --- src/ops.c Wed Mar 31 19:00:44 2004 *************** *** 94,102 **** static void shift_block __ARGS((oparg_T *oap, int amount)); static void block_insert __ARGS((oparg_T *oap, char_u *s, int b_insert, struct block_def*bdp)); #endif - #ifdef FEAT_EVAL - static char_u *get_expr_line __ARGS((void)); - #endif static void get_yank_register __ARGS((int regname, int writing)); static int stuff_yank __ARGS((int, char_u *)); static int put_in_typebuf __ARGS((char_u *s, int colon)); --- 94,99 ---- *************** *** 637,643 **** } #endif ! #if defined(FEAT_LISP) || defined(FEAT_CINDENT) /* * op_reindent - handle reindenting a block of lines. */ --- 634,640 ---- } #endif ! #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(PROTO) /* * op_reindent - handle reindenting a block of lines. */ *************** *** 721,727 **** } #endif /* defined(FEAT_LISP) || defined(FEAT_CINDENT) */ ! #ifdef FEAT_EVAL /* * Keep the last expression line here, for repeating. */ --- 718,724 ---- } #endif /* defined(FEAT_LISP) || defined(FEAT_CINDENT) */ ! #if defined(FEAT_EVAL) || defined(PROTO) /* * Keep the last expression line here, for repeating. */ *************** *** 762,768 **** * Get the result of the '=' register expression. * Returns a pointer to allocated memory, or NULL for failure. */ ! static char_u * get_expr_line() { char_u *expr_copy; --- 759,765 ---- * Get the result of the '=' register expression. * Returns a pointer to allocated memory, or NULL for failure. */ ! char_u * get_expr_line() { char_u *expr_copy; *** ../vim-6.2.441/src/proto/ex_getln.pro Sun Jan 18 21:27:18 2004 --- src/proto/ex_getln.pro Wed Mar 31 18:32:36 2004 *************** *** 27,32 **** --- 27,35 ---- int get_histtype __ARGS((char_u *name)); void add_to_history __ARGS((int histype, char_u *new_entry, int in_map, int sep)); int get_history_idx __ARGS((int histype)); + char_u *get_cmdline_str __ARGS((void)); + int get_cmdline_pos __ARGS((void)); + int set_cmdline_pos __ARGS((int pos)); char_u *get_history_entry __ARGS((int histype, int idx)); int clr_history __ARGS((int histype)); int del_history_entry __ARGS((int histype, char_u *str)); *** ../vim-6.2.441/src/proto/ops.pro Mon Mar 8 12:27:39 2004 --- src/proto/ops.pro Wed Mar 31 19:01:10 2004 *************** *** 8,13 **** --- 8,14 ---- void op_reindent __ARGS((oparg_T *oap, int (*how)(void))); int get_expr_register __ARGS((void)); void set_expr_line __ARGS((char_u *new_line)); + char_u *get_expr_line __ARGS((void)); int valid_yank_reg __ARGS((int regname, int writing)); void *get_register __ARGS((int name, int copy)); void put_register __ARGS((int name, void *reg)); *** ../vim-6.2.441/src/version.c Sun Apr 4 12:10:13 2004 --- src/version.c Sun Apr 4 12:30:29 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 442, /**/ -- hundred-and-one symptoms of being an internet addict: 262. Your computer has it's own phone line - but your daughter doesn't. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///