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 '.<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
+ 
+ 
*** ../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, <[email protected]>
  #             Sandor Kopanyi,  <[email protected]>
  #
! # 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, <[email protected]>
  #             Sandor Kopanyi,  <[email protected]>
  #
! # 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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui