| To: vim_dev@googlegroups.com |
| Subject: Patch 7.4.5 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| 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, |
| |
| |
| |
| |
| |
| |
| --- 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 '.<line1>.' '.<line2>) |
| + :com -range -addr=arguments RangeArguments :call add(g:lines, 'RangeArguments '.<line1>.' '.<line2>) |
| + :com -range=% -addr=arguments RangeArgumentsAll :call add(g:lines, 'RangeArgumentsAll '.<line1>.' '.<line2>) |
| + :com -range -addr=loaded_buffers RangeLoadedBuffers :call add(g:lines, 'RangeLoadedBuffers '.<line1>.' '.<line2>) |
| + :com -range=% -addr=loaded_buffers RangeLoadedBuffersAll :call add(g:lines, 'RangeLoadedBuffersAll '.<line1>.' '.<line2>) |
| + :com -range -addr=buffers RangeBuffers :call add(g:lines, 'RangeBuffers '.<line1>.' '.<line2>) |
| + :com -range=% -addr=buffers RangeBuffersAll :call add(g:lines, 'RangeBuffersAll '.<line1>.' '.<line2>) |
| + :com -range -addr=windows RangeWindows :call add(g:lines, 'RangeWindows '.<line1>.' '.<line2>) |
| + :com -range=% -addr=windows RangeWindowsAll :call add(g:lines, 'RangeWindowsAll '.<line1>.' '.<line2>) |
| + :com -range -addr=tabs RangeTabs :call add(g:lines, 'RangeTabs '.<line1>.' '.<line2>) |
| + :com -range=% -addr=tabs RangeTabsAll :call add(g:lines, 'RangeTabsAll '.<line1>.' '.<line2>) |
| + :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 |
| + |
| + |
| |
| |
| |
| |
| --- 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 |
| + |
| |
| |
| |
| *** 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 |
| |
| |
| |
| *** 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 \ |
| |
| |
| |
| *** 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 \ |
| |
| |
| |
| *** 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 \ |
| |
| |
| |
| *** 4,10 **** |
| # Authors: Zoltan Arpadffy, <arpadffy@polarhome.com> |
| # Sandor Kopanyi, <sandor.kopanyi@mailbox.hu> |
| # |
| ! # 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, <arpadffy@polarhome.com> |
| # Sandor Kopanyi, <sandor.kopanyi@mailbox.hu> |
| # |
| ! # 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 \ |
| |
| |
| |
| *** 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 \ |
| |
| |
| |
| *** 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: |
| |
| |
| |
| *** 1896,1901 **** |
| --- 1896,1902 ---- |
| test_breakindent \ |
| test_changelist \ |
| test_close_count \ |
| + test_command_count \ |
| test_eval \ |
| test_insertcount \ |
| test_listlbr \ |
| |
| |
| |
| *** 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), |
| |
| |
| |
| *** 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) |
| |
| |
| |
| *** 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}, |
| |
| |
| |
| *** 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 ---- |
| |
| |
| |
| *** 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 |
| |
| |
| |
| *** 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 /// |