break;
case ADDR_ARGUMENTS:
ea.line2 = curwin->w_arg_idx + 1;
+ if (ea.line2 > ARGCOUNT)
+ ea.line2 = ARGCOUNT;
break;
case ADDR_LOADED_BUFFERS:
case ADDR_BUFFERS:
* Exceptions:
* - the 'k' command can directly be followed by any character.
* - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
- * but :sre[wind] is another command, as are :scrip[tnames],
+ * but :sre[wind] is another command, as are :scr[iptnames],
* :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
* - the "d" command can directly be followed by 'l' or 'p' flag.
*/
lnum -= n;
else
lnum += n;
-
- switch (addr_type)
- {
- case ADDR_LINES:
- break;
- case ADDR_ARGUMENTS:
- if (lnum < 0)
- lnum = 0;
- else if (lnum >= ARGCOUNT)
- lnum = ARGCOUNT;
- break;
- case ADDR_TABS:
- if (lnum < 0)
- {
- lnum = 0;
- break;
- }
- if (lnum >= LAST_TAB_NR)
- lnum = LAST_TAB_NR;
- break;
- case ADDR_WINDOWS:
- if (lnum < 0)
- {
- lnum = 0;
- break;
- }
- if (lnum >= LAST_WIN_NR)
- lnum = LAST_WIN_NR;
- break;
- case ADDR_LOADED_BUFFERS:
- case ADDR_BUFFERS:
- if (lnum < firstbuf->b_fnum)
- {
- lnum = firstbuf->b_fnum;
- break;
- }
- if (lnum > lastbuf->b_fnum)
- lnum = lastbuf->b_fnum;
- break;
- }
}
} while (*cmd == '/' || *cmd == '?');
invalid_range(eap)
exarg_T *eap;
{
+ buf_T *buf;
if ( eap->line1 < 0
|| eap->line2 < 0
- || eap->line1 > eap->line2
- || ((eap->argt & RANGE)
- && !(eap->argt & NOTADR)
- && eap->line2 > curbuf->b_ml.ml_line_count
+ || eap->line1 > eap->line2)
+ return (char_u *)_(e_invrange);
+
+ if (eap->argt & RANGE)
+ {
+ switch(eap->addr_type)
+ {
+ case ADDR_LINES:
+ if (!(eap->argt & NOTADR)
+ && eap->line2 > curbuf->b_ml.ml_line_count
#ifdef FEAT_DIFF
- + (eap->cmdidx == CMD_diffget)
+ + (eap->cmdidx == CMD_diffget)
#endif
- ))
- return (char_u *)_(e_invrange);
+ )
+ return (char_u *)_(e_invrange);
+ break;
+ case ADDR_ARGUMENTS:
+ if (eap->line2 > ARGCOUNT + (!ARGCOUNT)) // add 1 if ARCOUNT is 0
+ return (char_u *)_(e_invrange);
+ break;
+ case ADDR_BUFFERS:
+ if (eap->line1 < firstbuf->b_fnum
+ || eap->line2 > lastbuf->b_fnum)
+ return (char_u *)_(e_invrange);
+ break;
+ case ADDR_LOADED_BUFFERS:
+ buf = firstbuf;
+ while (buf->b_ml.ml_mfp == NULL)
+ {
+ if (buf->b_next == NULL)
+ return (char_u *)_(e_invrange);
+ buf = buf->b_next;
+ }
+ if (eap->line1 < buf->b_fnum)
+ return (char_u *)_(e_invrange);
+ buf = lastbuf;
+ while (buf->b_ml.ml_mfp == NULL)
+ {
+ if (buf->b_prev == NULL)
+ return (char_u *)_(e_invrange);
+ buf = buf->b_prev;
+ }
+ if (eap->line2 > buf->b_fnum)
+ return (char_u *)_(e_invrange);
+ break;
+ case ADDR_WINDOWS:
+ if (eap->line1 < 1
+ || eap->line2 > LAST_WIN_NR)
+ return (char_u *)_(e_invrange);
+ break;
+ case ADDR_TABS:
+ if (eap->line2 > LAST_TAB_NR)
+ return (char_u *)_(e_invrange);
+ break;
+ }
+ }
return NULL;
}
Test for user command counts vim: set ft=vim :
STARTTEST
-:let g:lines = []
:so tiny.vim
+:let g:lines = []
:com -range=% RangeLines :call add(g:lines, 'RangeLines '.<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>)
:'<,'>RangeLines
:com -range=% -buffer LocalRangeLines :call add(g:lines, 'LocalRangeLines '.<line1>.' '.<line2>)
:'<,'>LocalRangeLines
+:b1
+ENDTEST
+
+STARTTEST
+:call add(g:lines, '')
+:%argd
+:arga a b c d
+:let v:errmsg = ''
+:5argu
+:call add(g:lines, '5argu ' . v:errmsg)
+:$argu
+:call add(g:lines, '4argu ' . expand('%:t'))
+:let v:errmsg = ''
+:1argu
+:call add(g:lines, '1argu ' . expand('%:t'))
+:let v:errmsg = ''
+:100b
+:call add(g:lines, '100b ' . v:errmsg)
+:split|split|split|split
+:let v:errmsg = ''
+:0close
+:call add(g:lines, '0close ' . v:errmsg)
+:$wincmd w
+:$close
+:call add(g:lines, '$close ' . winnr())
+:let v:errmsg = ''
+:$+close
+:call add(g:lines, '$+close ' . v:errmsg)
+:$tabe
+:call add(g:lines, '$tabe ' . tabpagenr())
+:let v:errmsg = ''
+:$+tabe
+:call add(g:lines, '$+tabe ' . v:errmsg)
+:only!
+:e x
+:0tabm
+:normal 1gt
+:call add(g:lines, '0tabm ' . expand('%:t'))
+:tabonly!
+:only!
:e! test.out
:call append(0, g:lines)
:w|qa!