To: vim_dev@googlegroups.com Subject: Patch 7.4.5 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.542 Problem: Using a range for window and buffer commands has a few problems. Cannot specify the type of range for a user command. Solution: Add the -addr argument for user commands. Fix problems. (Marcin Szamotulski) Files: src/testdir/test_command_count.in, src/testdir/test_command_count.ok src/testdir/Make_amiga.mak src/testdir/Make_dos.mak, src/testdir/Make_ming.mak, src/testdir/Make_os2.mak, src/testdir/Make_vms.mms, src/testdir/Makefile, runtime/doc/map.txt, src/Makefile, src/ex_cmds.h, src/ex_docmd.c, src/ex_getln.c, src/proto/ex_docmd.pro, src/vim.h, *** ../vim-7.4.541/src/testdir/test_command_count.in 2014-12-08 04:12:53.163981827 +0100 --- src/testdir/test_command_count.in 2014-12-08 03:25:41.562266976 +0100 *************** *** 0 **** --- 1,50 ---- + Test for user command counts vim: set ft=vim : + + STARTTEST + :let g:lines = [] + :so tiny.vim + :com -range RangeLines :call add(g:lines, 'Rangeg:Lines '..' '.) + :com -range -addr=arguments RangeArguments :call add(g:lines, 'RangeArguments '..' '.) + :com -range=% -addr=arguments RangeArgumentsAll :call add(g:lines, 'RangeArgumentsAll '..' '.) + :com -range -addr=loaded_buffers RangeLoadedBuffers :call add(g:lines, 'RangeLoadedBuffers '..' '.) + :com -range=% -addr=loaded_buffers RangeLoadedBuffersAll :call add(g:lines, 'RangeLoadedBuffersAll '..' '.) + :com -range -addr=buffers RangeBuffers :call add(g:lines, 'RangeBuffers '..' '.) + :com -range=% -addr=buffers RangeBuffersAll :call add(g:lines, 'RangeBuffersAll '..' '.) + :com -range -addr=windows RangeWindows :call add(g:lines, 'RangeWindows '..' '.) + :com -range=% -addr=windows RangeWindowsAll :call add(g:lines, 'RangeWindowsAll '..' '.) + :com -range -addr=tabs RangeTabs :call add(g:lines, 'RangeTabs '..' '.) + :com -range=% -addr=tabs RangeTabsAll :call add(g:lines, 'RangeTabsAll '..' '.) + :set hidden + :arga a b c d + :argdo echo "loading buffers" + :argu 3 + :.-,$-RangeArguments + :%RangeArguments + :RangeArgumentsAll + :N + :.RangeArguments + :split|split|split|split + :3wincmd w + :.,$RangeWindows + :%RangeWindows + :RangeWindowsAll + :only + :blast|bd + :.,$RangeLoadedBuffers + :%RangeLoadedBuffers + :RangeLoadedBuffersAll + :.,$RangeBuffers + :%RangeBuffers + :RangeBuffersAll + :tabe|tabe|tabe|tabe + :normal 2gt + :.,$RangeTabs + :%RangeTabs + :RangeTabsAll + :1tabonly + :e! test.out + :call append(0, g:lines) + :w|qa! + ENDTEST + + *** ../vim-7.4.541/src/testdir/test_command_count.ok 2014-12-08 04:12:53.163981827 +0100 --- src/testdir/test_command_count.ok 2014-12-08 03:26:11.769943969 +0100 *************** *** 0 **** --- 1,17 ---- + RangeArguments 2 4 + RangeArguments 1 5 + RangeArgumentsAll 1 5 + RangeArguments 2 2 + RangeWindows 3 5 + RangeWindows 1 5 + RangeWindowsAll 1 5 + RangeLoadedBuffers 2 4 + RangeLoadedBuffers 1 4 + RangeLoadedBuffersAll 1 4 + RangeBuffers 2 5 + RangeBuffers 1 5 + RangeBuffersAll 1 5 + RangeTabs 2 5 + RangeTabs 1 5 + RangeTabsAll 1 5 + *** ../vim-7.4.541/src/testdir/Make_amiga.mak 2014-11-27 16:22:42.742413039 +0100 --- src/testdir/Make_amiga.mak 2014-12-08 03:28:30.984456524 +0100 *************** *** 41,46 **** --- 41,47 ---- test_breakindent.out \ test_changelist.out \ test_close_count.out \ + test_command_count.out \ test_eval.out \ test_insertcount.out \ test_listlbr.out \ *************** *** 178,183 **** --- 179,185 ---- test_breakindent.out: test_breakindent.in test_changelist.out: test_changelist.in test_close_count.out: test_close_count.in + test_command_count.out: test_command_count.in test_eval.out: test_eval.in test_insertcount.out: test_insertcount.in test_listlbr.out: test_listlbr.in *** ../vim-7.4.541/src/testdir/Make_dos.mak 2014-11-27 16:22:42.742413039 +0100 --- src/testdir/Make_dos.mak 2014-12-08 03:28:43.168326713 +0100 *************** *** 40,45 **** --- 40,46 ---- test_breakindent.out \ test_changelist.out \ test_close_count.out \ + test_command_count.out \ test_eval.out \ test_insertcount.out \ test_listlbr.out \ *** ../vim-7.4.541/src/testdir/Make_ming.mak 2014-11-27 16:22:42.742413039 +0100 --- src/testdir/Make_ming.mak 2014-12-08 03:28:54.020208323 +0100 *************** *** 62,67 **** --- 62,68 ---- test_breakindent.out \ test_changelist.out \ test_close_count.out \ + test_command_count.out \ test_eval.out \ test_insertcount.out \ test_listlbr.out \ *** ../vim-7.4.541/src/testdir/Make_os2.mak 2014-11-27 16:22:42.742413039 +0100 --- src/testdir/Make_os2.mak 2014-12-08 03:29:03.304108543 +0100 *************** *** 42,47 **** --- 42,48 ---- test_breakindent.out \ test_changelist.out \ test_close_count.out \ + test_command_count.out \ test_eval.out \ test_insertcount.out \ test_listlbr.out \ *** ../vim-7.4.541/src/testdir/Make_vms.mms 2014-11-27 16:22:42.746412995 +0100 --- src/testdir/Make_vms.mms 2014-12-08 03:29:12.596009487 +0100 *************** *** 4,10 **** # Authors: Zoltan Arpadffy, # Sandor Kopanyi, # ! # Last change: 2014 Nov 27 # # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. # Edit the lines in the Configuration section below to select. --- 4,10 ---- # Authors: Zoltan Arpadffy, # Sandor Kopanyi, # ! # Last change: 2014 Dec 08 # # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. # Edit the lines in the Configuration section below to select. *************** *** 101,106 **** --- 101,107 ---- test_breakindent.out \ test_changelist.out \ test_close_count.out \ + test_command_count.out \ test_eval.out \ test_insertcount.out \ test_listlbr.out \ *** ../vim-7.4.541/src/testdir/Makefile 2014-11-27 16:22:42.746412995 +0100 --- src/testdir/Makefile 2014-12-08 03:29:36.519753429 +0100 *************** *** 38,43 **** --- 38,44 ---- test_breakindent.out \ test_changelist.out \ test_close_count.out \ + test_command_count.out \ test_eval.out \ test_insertcount.out \ test_listlbr.out \ *** ../vim-7.4.541/runtime/doc/map.txt 2014-02-23 23:38:58.820760280 +0100 --- runtime/doc/map.txt 2014-12-08 03:33:48.569056762 +0100 *************** *** 1344,1349 **** --- 1358,1376 ---- Note that -range=N and -count=N are mutually exclusive - only one should be specified. + *E889* *:command-addr* + It is possible that the special characters in the range like ., $ or % which + by default correspond to the current line, last line and the whole buffer, + relate to arguments, (loaded) buffers, windows or tab pages. + + Possible values are: + -addr=lines Range of lines (this is the default) + -addr=arguments Range for arguments + -addr=buffers Range for buffers (also not loaded buffers) + -addr=loaded_buffers Range for loaded buffers + -addr=windows Range for windows + -addr=tabs Range for tab pages + Special cases *:command-bang* *:command-bar* *:command-register* *:command-buffer* There are some special cases as well: *** ../vim-7.4.541/src/Makefile 2014-11-27 16:22:42.738413084 +0100 --- src/Makefile 2014-12-08 03:30:06.167435718 +0100 *************** *** 1896,1901 **** --- 1896,1902 ---- test_breakindent \ test_changelist \ test_close_count \ + test_command_count \ test_eval \ test_insertcount \ test_listlbr \ *** ../vim-7.4.541/src/ex_cmds.h 2014-11-27 16:22:42.742413039 +0100 --- src/ex_cmds.h 2014-12-08 03:30:59.278867940 +0100 *************** *** 63,69 **** #define ADDR_WINDOWS 1 #define ADDR_ARGUMENTS 2 #define ADDR_LOADED_BUFFERS 3 ! #define ADDR_UNLOADED_BUFFERS 4 #define ADDR_TABS 5 #ifndef DO_DECLARE_EXCMD --- 63,69 ---- #define ADDR_WINDOWS 1 #define ADDR_ARGUMENTS 2 #define ADDR_LOADED_BUFFERS 3 ! #define ADDR_BUFFERS 4 #define ADDR_TABS 5 #ifndef DO_DECLARE_EXCMD *************** *** 161,167 **** ADDR_LINES), EX(CMD_buffer, "buffer", ex_buffer, BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|EDITCMD|TRLBAR, ! ADDR_UNLOADED_BUFFERS), EX(CMD_bNext, "bNext", ex_bprevious, BANG|RANGE|NOTADR|COUNT|EDITCMD|TRLBAR, ADDR_LINES), --- 161,167 ---- ADDR_LINES), EX(CMD_buffer, "buffer", ex_buffer, BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|EDITCMD|TRLBAR, ! ADDR_BUFFERS), EX(CMD_bNext, "bNext", ex_bprevious, BANG|RANGE|NOTADR|COUNT|EDITCMD|TRLBAR, ADDR_LINES), *************** *** 227,233 **** ADDR_LOADED_BUFFERS), EX(CMD_bwipeout, "bwipeout", ex_bunload, BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR, ! ADDR_UNLOADED_BUFFERS), EX(CMD_change, "change", ex_change, BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|MODIFY, ADDR_LINES), --- 227,233 ---- ADDR_LOADED_BUFFERS), EX(CMD_bwipeout, "bwipeout", ex_bunload, BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR, ! ADDR_BUFFERS), EX(CMD_change, "change", ex_change, BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|MODIFY, ADDR_LINES), *************** *** 1184,1190 **** ADDR_LINES), EX(CMD_sbuffer, "sbuffer", ex_buffer, BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|EDITCMD|TRLBAR, ! ADDR_UNLOADED_BUFFERS), EX(CMD_sbNext, "sbNext", ex_bprevious, RANGE|NOTADR|COUNT|EDITCMD|TRLBAR, ADDR_LINES), --- 1184,1190 ---- ADDR_LINES), EX(CMD_sbuffer, "sbuffer", ex_buffer, BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|EDITCMD|TRLBAR, ! ADDR_BUFFERS), EX(CMD_sbNext, "sbNext", ex_bprevious, RANGE|NOTADR|COUNT|EDITCMD|TRLBAR, ADDR_LINES), *** ../vim-7.4.541/src/ex_docmd.c 2014-11-30 22:51:00.629191482 +0100 --- src/ex_docmd.c 2014-12-08 04:00:14.540095591 +0100 *************** *** 27,32 **** --- 27,33 ---- char_u *uc_rep; /* The command's replacement string */ long uc_def; /* The default value for a range/count */ int uc_compl; /* completion type */ + int uc_addr_type; /* The command's address type */ # ifdef FEAT_EVAL scid_T uc_scriptID; /* SID where the command was defined */ # ifdef FEAT_CMDL_COMPL *************** *** 2136,2142 **** --- 2137,2147 ---- ) ea.addr_type = cmdnames[(int)ea.cmdidx].cmd_addr_type; else + #ifdef FEAT_USR_CMDS + if (ea.cmdidx != CMD_USER) + #endif ea.addr_type = ADDR_LINES; + /* ea.addr_type for user commands is set by find_ucmd */ ea.cmd = cmd; /* repeat for all ',' or ';' separated addresses */ *************** *** 2157,2163 **** ea.line2 = curwin->w_arg_idx + 1; break; case ADDR_LOADED_BUFFERS: ! case ADDR_UNLOADED_BUFFERS: ea.line2 = curbuf->b_fnum; break; case ADDR_TABS: --- 2162,2168 ---- ea.line2 = curwin->w_arg_idx + 1; break; case ADDR_LOADED_BUFFERS: ! case ADDR_BUFFERS: ea.line2 = curbuf->b_fnum; break; case ADDR_TABS: *************** *** 2191,2208 **** buf = buf->b_prev; ea.line2 = buf->b_fnum; break; ! case ADDR_UNLOADED_BUFFERS: ea.line1 = firstbuf->b_fnum; ea.line2 = lastbuf->b_fnum; break; case ADDR_WINDOWS: case ADDR_TABS: ! errormsg = (char_u *)_(e_invrange); ! goto doend; break; case ADDR_ARGUMENTS: ! ea.line1 = 1; ! ea.line2 = ARGCOUNT; break; } ++ea.addr_count; --- 2196,2229 ---- buf = buf->b_prev; ea.line2 = buf->b_fnum; break; ! case ADDR_BUFFERS: ea.line1 = firstbuf->b_fnum; ea.line2 = lastbuf->b_fnum; break; case ADDR_WINDOWS: case ADDR_TABS: ! if (IS_USER_CMDIDX(ea.cmdidx)) ! { ! ea.line1 = 1; ! ea.line2 = ea.addr_type == ADDR_WINDOWS ! ? LAST_WIN_NR : LAST_TAB_NR; ! } ! else ! { ! /* there is no Vim command which uses '%' and ! * ADDR_WINDOWS or ADDR_TABS */ ! errormsg = (char_u *)_(e_invrange); ! goto doend; ! } break; case ADDR_ARGUMENTS: ! if (ARGCOUNT == 0) ! ea.line1 = ea.line2 = 0; ! else ! { ! ea.line1 = 1; ! ea.line2 = ARGCOUNT; ! } break; } ++ea.addr_count; *************** *** 2629,2636 **** if ((ea.argt & DFLALL) && ea.addr_count == 0) { ea.line1 = 1; ! ea.line2 = curbuf->b_ml.ml_line_count; } /* accept numbered register only when no count allowed (:put) */ --- 2650,2690 ---- if ((ea.argt & DFLALL) && ea.addr_count == 0) { + buf_T *buf; + ea.line1 = 1; ! switch (ea.addr_type) ! { ! case ADDR_LINES: ! ea.line2 = curbuf->b_ml.ml_line_count; ! break; ! case ADDR_LOADED_BUFFERS: ! buf = firstbuf; ! while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) ! buf = buf->b_next; ! ea.line1 = buf->b_fnum; ! buf = lastbuf; ! while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) ! buf = buf->b_prev; ! ea.line2 = buf->b_fnum; ! break; ! case ADDR_BUFFERS: ! ea.line1 = firstbuf->b_fnum; ! ea.line2 = lastbuf->b_fnum; ! break; ! case ADDR_WINDOWS: ! ea.line2 = LAST_WIN_NR; ! break; ! case ADDR_TABS: ! ea.line2 = LAST_TAB_NR; ! break; ! case ADDR_ARGUMENTS: ! if (ARGCOUNT == 0) ! ea.line1 = ea.line2 = 0; ! else ! ea.line2 = ARGCOUNT; ! break; ! } } /* accept numbered register only when no count allowed (:put) */ *************** *** 3211,3216 **** --- 3265,3271 ---- eap->cmdidx = CMD_USER_BUF; eap->argt = (long)uc->uc_argt; eap->useridx = j; + eap->addr_type = uc->uc_addr_type; # ifdef FEAT_CMDL_COMPL if (compl != NULL) *************** *** 3839,3845 **** return NULL; } ! /* For the -complete and -nargs attributes, we complete * their arguments as well. */ if (STRNICMP(arg, "complete", p - arg) == 0) --- 3894,3900 ---- return NULL; } ! /* For the -complete, -nargs and -addr attributes, we complete * their arguments as well. */ if (STRNICMP(arg, "complete", p - arg) == 0) *************** *** 3854,3859 **** --- 3909,3920 ---- xp->xp_pattern = p + 1; return NULL; } + else if (STRNICMP(arg, "addr", p - arg) == 0) + { + xp->xp_context = EXPAND_USER_ADDR_TYPE; + xp->xp_pattern = p + 1; + return NULL; + } return NULL; } arg = skipwhite(p); *************** *** 4264,4269 **** --- 4325,4331 ---- pos_T pos; pos_T *fp; linenr_T lnum; + buf_T *buf; cmd = skipwhite(*ptr); lnum = MAXLNUM; *************** *** 4285,4291 **** lnum = curwin->w_arg_idx + 1; break; case ADDR_LOADED_BUFFERS: ! case ADDR_UNLOADED_BUFFERS: lnum = curbuf->b_fnum; break; case ADDR_TABS: --- 4347,4353 ---- lnum = curwin->w_arg_idx + 1; break; case ADDR_LOADED_BUFFERS: ! case ADDR_BUFFERS: lnum = curbuf->b_fnum; break; case ADDR_TABS: *************** *** 4308,4314 **** lnum = ARGCOUNT; break; case ADDR_LOADED_BUFFERS: ! case ADDR_UNLOADED_BUFFERS: lnum = lastbuf->b_fnum; break; case ADDR_TABS: --- 4370,4385 ---- lnum = ARGCOUNT; break; case ADDR_LOADED_BUFFERS: ! buf = lastbuf; ! while (buf->b_ml.ml_mfp == NULL) ! { ! if (buf->b_prev == NULL) ! break; ! buf = buf->b_prev; ! } ! lnum = buf->b_fnum; ! break; ! case ADDR_BUFFERS: lnum = lastbuf->b_fnum; break; case ADDR_TABS: *************** *** 4477,4483 **** lnum = curwin->w_arg_idx + 1; break; case ADDR_LOADED_BUFFERS: ! case ADDR_UNLOADED_BUFFERS: lnum = curbuf->b_fnum; break; case ADDR_TABS: --- 4548,4554 ---- lnum = curwin->w_arg_idx + 1; break; case ADDR_LOADED_BUFFERS: ! case ADDR_BUFFERS: lnum = curbuf->b_fnum; break; case ADDR_TABS: *************** *** 4495,4501 **** else n = getdigits(&cmd); if (addr_type == ADDR_LOADED_BUFFERS ! || addr_type == ADDR_UNLOADED_BUFFERS) lnum = compute_buffer_local_count(addr_type, lnum, (i == '-') ? -1 * n : n); else if (i == '-') lnum -= n; --- 4566,4572 ---- else n = getdigits(&cmd); if (addr_type == ADDR_LOADED_BUFFERS ! || addr_type == ADDR_BUFFERS) lnum = compute_buffer_local_count(addr_type, lnum, (i == '-') ? -1 * n : n); else if (i == '-') lnum -= n; *************** *** 4531,4537 **** lnum = LAST_WIN_NR; break; case ADDR_LOADED_BUFFERS: ! case ADDR_UNLOADED_BUFFERS: if (lnum < firstbuf->b_fnum) { lnum = firstbuf->b_fnum; --- 4602,4608 ---- lnum = LAST_WIN_NR; break; case ADDR_LOADED_BUFFERS: ! case ADDR_BUFFERS: if (lnum < firstbuf->b_fnum) { lnum = firstbuf->b_fnum; *************** *** 5585,5598 **** #endif #if defined(FEAT_USR_CMDS) || defined(PROTO) ! static int uc_add_command __ARGS((char_u *name, size_t name_len, char_u *rep, long argt, long def, int flags, int compl, char_u *compl_arg, int force)); static void uc_list __ARGS((char_u *name, size_t name_len)); ! static int uc_scan_attr __ARGS((char_u *attr, size_t len, long *argt, long *def, int *flags, int *compl, char_u **compl_arg)); static char_u *uc_split_args __ARGS((char_u *arg, size_t *lenp)); static size_t uc_check_code __ARGS((char_u *code, size_t len, char_u *buf, ucmd_T *cmd, exarg_T *eap, char_u **split_buf, size_t *split_len)); static int ! uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, force) char_u *name; size_t name_len; char_u *rep; --- 5656,5669 ---- #endif #if defined(FEAT_USR_CMDS) || defined(PROTO) ! static int uc_add_command __ARGS((char_u *name, size_t name_len, char_u *rep, long argt, long def, int flags, int compl, char_u *compl_arg, int addr_type, int force)); static void uc_list __ARGS((char_u *name, size_t name_len)); ! static int uc_scan_attr __ARGS((char_u *attr, size_t len, long *argt, long *def, int *flags, int *compl, char_u **compl_arg, int* attr_type_arg)); static char_u *uc_split_args __ARGS((char_u *arg, size_t *lenp)); static size_t uc_check_code __ARGS((char_u *code, size_t len, char_u *buf, ucmd_T *cmd, exarg_T *eap, char_u **split_buf, size_t *split_len)); static int ! uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, addr_type, force) char_u *name; size_t name_len; char_u *rep; *************** *** 5601,5606 **** --- 5672,5678 ---- int flags; int compl; char_u *compl_arg; + int addr_type; int force; { ucmd_T *cmd = NULL; *************** *** 5695,5700 **** --- 5767,5773 ---- cmd->uc_compl_arg = compl_arg; # endif #endif + cmd->uc_addr_type = addr_type; return OK; *************** *** 5707,5712 **** --- 5780,5802 ---- } #endif + #if defined(FEAT_USR_CMDS) + static struct + { + int expand; + char *name; + } addr_type_complete[] = + { + {ADDR_ARGUMENTS, "arguments"}, + {ADDR_LINES, "lines"}, + {ADDR_LOADED_BUFFERS, "loaded_buffers"}, + {ADDR_TABS, "tabs"}, + {ADDR_BUFFERS, "buffers"}, + {ADDR_WINDOWS, "windows"}, + {-1, NULL} + }; + #endif + #if defined(FEAT_USR_CMDS) || defined(FEAT_EVAL) || defined(PROTO) /* * List of names for completion for ":command" with the EXPAND_ flag. *************** *** 5794,5800 **** /* Put out the title first time */ if (!found) ! MSG_PUTS_TITLE(_("\n Name Args Range Complete Definition")); found = TRUE; msg_putchar('\n'); if (got_int) --- 5884,5890 ---- /* Put out the title first time */ if (!found) ! MSG_PUTS_TITLE(_("\n Name Args Address Complete Definition")); found = TRUE; msg_putchar('\n'); if (got_int) *************** *** 5855,5860 **** --- 5945,5964 ---- IObuff[len++] = ' '; } while (len < 11); + /* Address Type */ + for (j = 0; addr_type_complete[j].expand != -1; ++j) + if (addr_type_complete[j].expand != ADDR_LINES + && addr_type_complete[j].expand == cmd->uc_addr_type) + { + STRCPY(IObuff + len, addr_type_complete[j].name); + len += (int)STRLEN(IObuff + len); + break; + } + + do { + IObuff[len++] = ' '; + } while (len < 21); + /* Completion */ for (j = 0; command_complete[j].expand != 0; ++j) if (command_complete[j].expand == cmd->uc_compl) *************** *** 5866,5872 **** do { IObuff[len++] = ' '; ! } while (len < 21); IObuff[len] = '\0'; msg_outtrans(IObuff); --- 5970,5976 ---- do { IObuff[len++] = ' '; ! } while (len < 35); IObuff[len] = '\0'; msg_outtrans(IObuff); *************** *** 5906,5912 **** } static int ! uc_scan_attr(attr, len, argt, def, flags, compl, compl_arg) char_u *attr; size_t len; long *argt; --- 6010,6016 ---- } static int ! uc_scan_attr(attr, len, argt, def, flags, compl, compl_arg, addr_type_arg) char_u *attr; size_t len; long *argt; *************** *** 5914,5919 **** --- 6018,6024 ---- int *flags; int *compl; char_u **compl_arg; + int *addr_type_arg; { char_u *p; *************** *** 6032,6037 **** --- 6137,6156 ---- == FAIL) return FAIL; } + else if (STRNICMP(attr, "addr", attrlen) == 0) + { + *argt |= RANGE; + if (val == NULL) + { + EMSG(_("E179: argument required for -addr")); + return FAIL; + } + if (parse_addr_type_arg(val, (int)vallen, argt, addr_type_arg) + == FAIL) + return FAIL; + if (addr_type_arg != ADDR_LINES) + *argt |= (ZEROR | NOTADR) ; + } else { char_u ch = attr[len]; *************** *** 6060,6065 **** --- 6179,6185 ---- int flags = 0; int compl = EXPAND_NOTHING; char_u *compl_arg = NULL; + int addr_type_arg = ADDR_LINES; int has_attr = (eap->arg[0] == '-'); int name_len; *************** *** 6070,6076 **** { ++p; end = skiptowhite(p); ! if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg) == FAIL) return; p = skipwhite(end); --- 6190,6196 ---- { ++p; end = skiptowhite(p); ! if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg, &addr_type_arg) == FAIL) return; p = skipwhite(end); *************** *** 6111,6117 **** } else uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg, ! eap->forceit); } /* --- 6231,6237 ---- } else uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg, ! addr_type_arg, eap->forceit); } /* *************** *** 6652,6657 **** --- 6772,6788 ---- } /* + * Function given to ExpandGeneric() to obtain the list of user address type names. + */ + char_u * + get_user_cmd_addr_type(xp, idx) + expand_T *xp UNUSED; + int idx; + { + return (char_u *)addr_type_complete[idx].name; + } + + /* * Function given to ExpandGeneric() to obtain the list of user command * attributes. */ *************** *** 6661,6668 **** int idx; { static char *user_cmd_flags[] = ! {"bang", "bar", "buffer", "complete", "count", ! "nargs", "range", "register"}; if (idx >= (int)(sizeof(user_cmd_flags) / sizeof(user_cmd_flags[0]))) return NULL; --- 6792,6799 ---- int idx; { static char *user_cmd_flags[] = ! {"addr", "bang", "bar", "buffer", "complete", ! "count", "nargs", "range", "register"}; if (idx >= (int)(sizeof(user_cmd_flags) / sizeof(user_cmd_flags[0]))) return NULL; *************** *** 6696,6701 **** --- 6827,6869 ---- } # endif /* FEAT_CMDL_COMPL */ + /* + * Parse address type argument + */ + int + parse_addr_type_arg(value, vallen, argt, addr_type_arg) + char_u *value; + int vallen; + long *argt; + int *addr_type_arg; + { + int i, a, b; + for (i = 0; addr_type_complete[i].expand != -1; ++i) + { + a = (int)STRLEN(addr_type_complete[i].name) == vallen; + b = STRNCMP(value, addr_type_complete[i].name, vallen) == 0; + if (a && b) + { + *addr_type_arg = addr_type_complete[i].expand; + break; + } + } + + if (addr_type_complete[i].expand == -1) + { + char_u *err = value; + for (i=0; err[i] == NUL || !vim_iswhite(err[i]); i++); + err[i] = NUL; + EMSG2(_("E180: Invalid address type value: %s"), err); + return FAIL; + } + + if (*addr_type_arg != ADDR_LINES) + *argt |= NOTADR; + + return OK; + } + #endif /* FEAT_USR_CMDS */ #if defined(FEAT_USR_CMDS) || defined(FEAT_EVAL) || defined(PROTO) *** ../vim-7.4.541/src/ex_getln.c 2014-09-09 18:45:45.884551705 +0200 --- src/ex_getln.c 2014-12-08 03:30:59.286867854 +0100 *************** *** 4697,4702 **** --- 4697,4703 ---- #endif #ifdef FEAT_USR_CMDS {EXPAND_USER_COMMANDS, get_user_commands, FALSE, TRUE}, + {EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, FALSE, TRUE}, {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE}, {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE}, {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE}, *** ../vim-7.4.541/src/proto/ex_docmd.pro 2014-04-01 17:49:40.140891378 +0200 --- src/proto/ex_docmd.pro 2014-12-08 03:55:53.314888997 +0100 *************** *** 19,27 **** --- 19,29 ---- void ex_comclear __ARGS((exarg_T *eap)); void uc_clear __ARGS((garray_T *gap)); char_u *get_user_commands __ARGS((expand_T *xp, int idx)); + char_u *get_user_cmd_addr_type __ARGS((expand_T *xp, int idx)); char_u *get_user_cmd_flags __ARGS((expand_T *xp, int idx)); char_u *get_user_cmd_nargs __ARGS((expand_T *xp, int idx)); char_u *get_user_cmd_complete __ARGS((expand_T *xp, int idx)); + int parse_addr_type_arg __ARGS((char_u *value, int vallen, long *argt, int *addr_type_arg)); int parse_compl_arg __ARGS((char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg)); void not_exiting __ARGS((void)); void tabpage_close __ARGS((int forceit)); *************** *** 43,48 **** --- 45,51 ---- void post_chdir __ARGS((int local)); void ex_cd __ARGS((exarg_T *eap)); void do_sleep __ARGS((long msec)); + void ex_may_print __ARGS((exarg_T *eap)); int vim_mkdir_emsg __ARGS((char_u *name, int prot)); FILE *open_exfile __ARGS((char_u *fname, int forceit, char *mode)); void update_topline_cursor __ARGS((void)); *************** *** 54,58 **** int put_line __ARGS((FILE *fd, char *s)); void dialog_msg __ARGS((char_u *buff, char *format, char_u *fname)); char_u *get_behave_arg __ARGS((expand_T *xp, int idx)); - void ex_may_print __ARGS((exarg_T *eap)); /* vim: set ft=c : */ --- 57,60 ---- *** ../vim-7.4.541/src/vim.h 2014-11-27 19:14:45.080940970 +0100 --- src/vim.h 2014-12-08 03:30:59.290867811 +0100 *************** *** 798,803 **** --- 798,804 ---- #define EXPAND_HISTORY 41 #define EXPAND_USER 42 #define EXPAND_SYNTIME 43 + #define EXPAND_USER_ADDR_TYPE 44 /* Values for exmode_active (0 is no exmode) */ #define EXMODE_NORMAL 1 *** ../vim-7.4.541/src/version.c 2014-12-07 00:18:27.528202992 +0100 --- src/version.c 2014-12-08 03:32:08.402128425 +0100 *************** *** 743,744 **** --- 743,746 ---- { /* Add new patch number below this line */ + /**/ + 542, /**/ -- CRONE: Who sent you? ARTHUR: The Knights Who Say GNU! CRONE: Aaaagh! (she looks around in rear) No! We have no licenses here. "Monty Python and the Holy editor wars" PYTHON (MONTY) SOFTWARE LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///