vim-patch:7.4.530-531

Specify different kinds of counts for commands.
Updated ex commands generator scripts.

Includes fixes to comments from patch 7.4.531

Original message:

Problem:    Many commands take a count or range that is not using line
            numbers.
Solution:   For each command specify what kind of count it uses.  For
            windows, buffers and arguments have "$" and "." have a
relevant
            meaning. (Marcin Szamotulski)

https://code.google.com/p/vim/source/detail?r=v7-4-530
https://code.google.com/p/vim/source/detail?r=v7-4-531

Add legacy tests for 7.4.530

https://code.google.com/p/vim/source/detail?r=1e6d87a36dcdca231721dde8cbbc26610fb3df27
This commit is contained in:
Felipe Morales 2015-01-10 20:27:17 -03:00
parent 6a8862ded4
commit 86330fdd3f
12 changed files with 1235 additions and 80 deletions

View File

@ -61,16 +61,25 @@ In the GUI tab pages line you can use the right mouse button to open menu.
:[count]tabe[dit] *:tabe* *:tabedit* *:tabnew*
:[count]tabnew
Open a new tab page with an empty window, after the current
tab page. For [count] see |:tab| below.
tab page. If [count] is given the new tab page appears after
the tabpage [count] otherwise the new tab page will appear
after the current one. >
:tabnew " opens tabpage after the current one
:.tabnew " as above
:+tabnew " opens tabpage after the next tab page
" note: it is one further than :tabnew
:-tabnew " opens tabpage before the current
:0tabnew " opens tabpage before the first one
:$tabnew " opens tabpage after the last one
:[count]tabe[dit] [++opt] [+cmd] {file}
:[count]tabnew [++opt] [+cmd] {file}
Open a new tab page and edit {file}, like with |:edit|.
For [count] see |:tab| below.
For [count] see |:tabnew| above.
:[count]tabf[ind] [++opt] [+cmd] {file} *:tabf* *:tabfind*
Open a new tab page and edit {file} in 'path', like with
|:find|. For [count] see |:tab| below.
|:find|. For [count] see |:tabnew| above.
{not available when the |+file_in_path| feature was disabled
at compile time}
@ -110,12 +119,18 @@ something else.
- When 'hidden' is not set, [!] is not used, a buffer has
changes, and there is no other window on this buffer.
Changes to the buffer are not written and won't get lost, so
this is a "safe" command.
this is a "safe" command. >
:tabclose " close the current tab page
:{count}tabc[lose][!]
:tabc[lose][!] {count}
Close tab page {count}. Fails in the same way as `:tabclose`
above.
above. >
:-tabclose " close the previous tab page
:+tabclose " close the next tab page
:1tabclose " close the first tab page
:$tabclose " close the last tab page
<
*:tabo* *:tabonly*
:tabo[nly][!] Close all other tab pages.
When the 'hidden' option is set, all buffers in closed windows
@ -124,7 +139,16 @@ something else.
modified buffers are written. Otherwise, windows that have
buffers that are modified are not removed, unless the [!] is
given, then they become hidden. But modified buffers are
never abandoned, so changes cannot get lost.
never abandoned, so changes cannot get lost. >
:tabonly " close all tab pages except the current one
:{count}tabo[nly][!]
Close all tab pages except the {count}th one. >
:.tabonly " one
:-tabonly " close all tab pages except the previous one
:+tabonly " close all tab pages except the next one
:1tabonly " close all tab pages except the first one
:$tabonly " close all tab pages except the last one.
SWITCHING TO ANOTHER TAB PAGE:
@ -176,8 +200,15 @@ REORDERING TAB PAGES:
:[N]tabm[ove]
Move the current tab page to after tab page N. Use zero to
make the current tab page the first one. Without N the tab
page is made the last one.
page is made the last one. >
:-tabmove " move the tab page to the left
:tabmove " move the tab page to the right
:.tabmove " as above
:+tabmove " as above
:0tabmove " move the tab page to the beginning of the tab
" list
:$tabmove " move the tab page to the end of the tab list
<
:tabm[ove] +[N]
:tabm[ove] -[N]
Move the current tab page N places to the right (with +) or to

View File

@ -263,28 +263,54 @@ left of the Vim window.
Closing a window
----------------
:q[uit]
:{count}q[uit]
CTRL-W q *CTRL-W_q*
CTRL-W CTRL-Q *CTRL-W_CTRL-Q*
:q[uit] Quit current window. When quitting the last window (not
counting a help window), exit Vim.
Without {count}: Quit the current window. If {count} is
given quit the {count} window
When quitting the last window (not counting a help window),
exit Vim.
When 'hidden' is set, and there is only one window for the
current buffer, it becomes hidden.
When 'hidden' is not set, and there is only one window for the
current buffer, and the buffer was changed, the command fails.
(Note: CTRL-Q does not work on all terminals)
:q[uit]! Quit current window. If this was the last window for a buffer,
any changes to that buffer are lost. When quitting the last
window (not counting help windows), exit Vim. The contents of
the buffer are lost, even when 'hidden' is set.
current buffer, it becomes hidden. When 'hidden' is not set,
and there is only one window for the current buffer, and the
buffer was changed, the command fails.
(Note: CTRL-Q does not work on all terminals).
If [count] is greater than the last window number the last
window will be closed: >
:1quit " quit the first window
:$quit " quit the last window
:9quit " quit the last window
" if there are less than windows opened
:-quit " quit the previous window
:+quit " quit the next window
:+2quit " will also work as expected
<
:q[uit]!
:{count}q[uit]!
Without {count}: Quit the current window. If {count} is
given quit the {count} window
If this was the last window for a buffer, any changes to that
buffer are lost. When quitting the last window (not counting
help windows), exit Vim. The contents of the buffer are lost,
even when 'hidden' is set.
:clo[se][!]
:{count}clo[se][!]
CTRL-W c *CTRL-W_c* *:clo* *:close*
:clo[se][!] Close current window. When the 'hidden' option is set, or
when the buffer was changed and the [!] is used, the buffer
becomes hidden (unless there is another window editing it).
Without {count}: Close the current window. If given close the
{count} window.
When 'hidden' is set, or when the buffer was changed and the
[!] is used, the buffer becomes hidden (unless there is another
window editing it).
When there is only one window in the current tab page and
there is another tab page, this closes the current tab page.
|tab-page|.
This command fails when: *E444*
- There is only one window on the screen.
- When 'hidden' is not set, [!] is not used, the buffer has
@ -297,29 +323,38 @@ CTRL-W CTRL-C *CTRL-W_CTRL-C*
window, but that does not work, because the CTRL-C cancels the
command.
*:hide*
:hid[e] Quit current window, unless it is the last window on the
screen. The buffer becomes hidden (unless there is another
window editing it or 'bufhidden' is "unload" or "delete").
If the window is the last one in the current tab page the tab
page is closed. |tab-page|
*:hide*
:hid[e]
:{count}hid[e]
Quit the current window, unless it is the last window on the
screen. For {count} see |:quit|.
The buffer becomes hidden (unless there is another window
editing it or 'bufhidden' is `unload` or `delete`). If the
window is the last one in the current tab page the tab page is
closed. |tab-page|
The value of 'hidden' is irrelevant for this command.
Changes to the buffer are not written and won't get lost, so
this is a "safe" command.
:hid[e] {cmd} Execute {cmd} with 'hidden' is set. The previous value of
:hid[e] {cmd} Execute {cmd} with 'hidden' set. The previous value of
'hidden' is restored after {cmd} has been executed.
Example: >
:hide edit Makefile
< This will edit "Makefile", and hide the current buffer if it
has any changes.
:on[ly][!]
:{count}on[ly][!]
CTRL-W o *CTRL-W_o* *E445*
CTRL-W CTRL-O *CTRL-W_CTRL-O* *:on* *:only*
:on[ly][!] Make the current window the only one on the screen. All other
windows are closed.
Make the current window the only one on the screen. All other
windows are closed. For {count} see |:quit|.
When the 'hidden' option is set, all buffers in closed windows
become hidden.
When 'hidden' is not set, and the 'autowrite' option is set,
modified buffers are written. Otherwise, windows that have
buffers that are modified are not removed, unless the [!] is

View File

@ -67,8 +67,9 @@ for i, cmd in ipairs(defs) do
[%s] = {
.cmd_name = (char_u *) "%s",
.cmd_func = &%s,
.cmd_argt = %u
}]], enumname, cmd.command, cmd.func, cmd.flags))
.cmd_argt = %uL,
.cmd_addr_type = %i
}]], enumname, cmd.command, cmd.func, cmd.flags, cmd.addr_type))
end
defsfile:write([[

File diff suppressed because it is too large Load Diff

View File

@ -71,6 +71,14 @@
#define WORD1 (EXTRA | NOSPC) /* one extra word allowed */
#define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */
// values for cmd_addr_type
#define ADDR_LINES 0
#define ADDR_WINDOWS 1
#define ADDR_ARGUMENTS 2
#define ADDR_LOADED_BUFFERS 3
#define ADDR_UNLOADED_BUFFERS 4
#define ADDR_TABS 5
typedef struct exarg exarg_T;
/* behavior for bad character, "++bad=" argument */
@ -87,6 +95,7 @@ typedef struct cmdname {
char_u *cmd_name; ///< Name of the command.
ex_func_T cmd_func; ///< Function with implementation of this command.
uint32_t cmd_argt; ///< Relevant flags from the declared above.
int cmd_addr_type; ///< Flag for address type
} CommandDefinition;
/// Arguments used for Ex commands.
@ -102,6 +111,7 @@ struct exarg {
int addr_count; ///< the number of addresses given
linenr_T line1; ///< the first line number
linenr_T line2; ///< the second line number or count
int addr_type; ///< type of the count/range
int flags; ///< extra flags after count: EXFLAG_
char_u *do_ecmd_cmd; ///< +command arg to be used in edited file
linenr_T do_ecmd_lnum; ///< the line number in an edited file

View File

@ -1065,6 +1065,33 @@ void * getline_cookie(LineGetter fgetline,
return cp;
}
/*
* Helper function to apply an offset for buffer commands, i.e. ":bdelete",
* ":bwipeout", etc.
* Returns the buffer number.
*/
static int compute_buffer_local_count(int addr_type, int lnum, int offset)
{
buf_T *buf;
int count = offset;
buf = firstbuf;
while (buf->b_next != NULL && buf->b_fnum < lnum)
buf = buf->b_next;
while (count != 0) {
count += (count < 0) ? 1 : -1;
if (buf->b_prev == NULL)
break;
buf = (count < 0) ? buf->b_prev : buf->b_next;
if (addr_type == ADDR_LOADED_BUFFERS)
/* skip over unloaded buffers */
while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) {
buf = (count < 0) ? buf->b_prev : buf->b_next;
}
}
return buf->b_fnum;
}
/*
* Execute one Ex command.
*
@ -1072,10 +1099,11 @@ void * getline_cookie(LineGetter fgetline,
*
* 1. skip comment lines and leading space
* 2. handle command modifiers
* 3. parse range
* 4. parse command
* 5. parse arguments
* 6. switch on command name
* 3. skip over the range to find the command
* 4. parse the range
* 5. parse the command
* 6. parse arguments
* 7. switch on command name
*
* Note: "fgetline" can be NULL.
*
@ -1100,6 +1128,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
int did_sandbox = FALSE;
cmdmod_T save_cmdmod;
int ni; /* set when Not Implemented */
win_T *wp;
tabpage_T *tp;
char_u *cmd;
memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
@ -1132,7 +1163,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.cmd = *cmdlinep;
for (;; ) {
/*
* 1. skip comment lines and leading white space and colons
* 1. Skip comment lines and leading white space and colons.
*/
while (*ea.cmd == ' ' || *ea.cmd == '\t' || *ea.cmd == ':')
++ea.cmd;
@ -1155,7 +1186,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
/*
* 2. handle command modifiers.
* 2. Handle command modifiers.
*/
p = ea.cmd;
if (ascii_isdigit(*ea.cmd))
@ -1319,8 +1350,18 @@ static char_u * do_one_cmd(char_u **cmdlinep,
(void)do_intthrow(cstack);
}
// 3. Skip over the range to find the command. Let "p" point to after it.
//
// We need the command to know what kind of range it uses.
cmd = ea.cmd;
ea.cmd = skip_range(ea.cmd, NULL);
if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
ea.cmd = skipwhite(ea.cmd + 1);
p = find_command(&ea, NULL);
/*
* 3. parse a range specifier of the form: addr [,addr] [;addr] ..
* 4. Parse a range specifier of the form: addr [,addr] [;addr] ..
*
* where 'addr' is:
*
@ -1336,25 +1377,82 @@ static char_u * do_one_cmd(char_u **cmdlinep,
* is equal to the lower.
*/
if (ea.cmdidx != CMD_SIZE) {
ea.addr_type = cmdnames[(int)ea.cmdidx].cmd_addr_type;
} else {
ea.addr_type = ADDR_LINES;
}
ea.cmd = cmd;
/* repeat for all ',' or ';' separated addresses */
for (;; ) {
ea.line1 = ea.line2;
ea.line2 = curwin->w_cursor.lnum; /* default is current line number */
switch (ea.addr_type) {
case ADDR_LINES:
// default is current line number
ea.line2 = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
lnum = 0;
for (wp = firstwin; wp != NULL; wp = wp->w_next) {
lnum++;
if (wp == curwin)
break;
}
ea.line2 = lnum;
break;
case ADDR_ARGUMENTS:
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:
lnum = 0;
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
lnum++;
if (tp == curtab)
break;
}
ea.line2 = lnum;
break;
}
ea.cmd = skipwhite(ea.cmd);
lnum = get_address(&ea.cmd, ea.skip, ea.addr_count == 0);
lnum = get_address(&ea.cmd, ea.addr_type, ea.skip, ea.addr_count == 0);
if (ea.cmd == NULL) /* error detected */
goto doend;
if (lnum == MAXLNUM) {
if (*ea.cmd == '%') { /* '%' - all lines */
++ea.cmd;
ea.line1 = 1;
ea.line2 = curbuf->b_ml.ml_line_count;
switch (ea.addr_type) {
case ADDR_LINES:
ea.line1 = 1;
ea.line2 = curbuf->b_ml.ml_line_count;
break;
case ADDR_WINDOWS:
case ADDR_LOADED_BUFFERS:
case ADDR_UNLOADED_BUFFERS:
case ADDR_TABS:
errormsg = (char_u *)_(e_invrange);
goto doend;
break;
case ADDR_ARGUMENTS:
ea.line1 = 1;
ea.line2 = ARGCOUNT;
break;
}
++ea.addr_count;
}
/* '*' - visual area */
else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) {
pos_T *fp;
if (ea.addr_type != ADDR_LINES) {
errormsg = (char_u *)_(e_invrange);
goto doend;
}
++ea.cmd;
if (!ea.skip) {
fp = getmark('<', FALSE);
@ -1392,7 +1490,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
check_cursor_lnum();
/*
* 4. parse command
* 5. Parse the command.
*/
/*
@ -1446,9 +1544,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend;
}
/* Find the command and let "p" point to after it. */
p = find_command(&ea, NULL);
// If this looks like an undefined user command and there are CmdUndefined
// autocommands defined, trigger the matching autocommands.
if (p != NULL && ea.cmdidx == CMD_SIZE && !ea.skip
@ -1502,7 +1597,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.forceit = FALSE;
/*
* 5. parse arguments
* 6. Parse arguments.
*/
if (!IS_USER_CMDIDX(ea.cmdidx)) {
ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt;
@ -1888,7 +1983,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
/*
* 6. switch on command name
* 7. Switch on command name.
*
* The "ea" structure holds the arguments that can be used.
*/
@ -3098,12 +3193,11 @@ skip_range (
*
* Return MAXLNUM when no Ex address was found.
*/
static linenr_T
get_address (
char_u **ptr,
int skip, /* only skip the address, don't use it */
int to_other_file /* flag: may jump to other file */
)
static linenr_T get_address(char_u **ptr,
int addr_type, // flag: one of ADDR_LINES, ...
int skip, // only skip the address, don't use it
int to_other_file // flag: may jump to other file
)
{
int c;
int i;
@ -3112,6 +3206,9 @@ get_address (
pos_T pos;
pos_T *fp;
linenr_T lnum;
win_T *wp;
tabpage_T *tp;
buf_T *buf;
cmd = skipwhite(*ptr);
lnum = MAXLNUM;
@ -3119,12 +3216,68 @@ get_address (
switch (*cmd) {
case '.': /* '.' - Cursor position */
++cmd;
lnum = curwin->w_cursor.lnum;
switch (addr_type) {
case ADDR_LINES:
lnum = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
lnum = 0;
for (wp = firstwin; wp != NULL; wp = wp->w_next) {
lnum++;
if (wp == curwin)
break;
}
break;
case ADDR_ARGUMENTS:
lnum = curwin->w_arg_idx + 1;
break;
case ADDR_LOADED_BUFFERS:
case ADDR_UNLOADED_BUFFERS:
lnum = curbuf->b_fnum;
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
lnum++;
if (tp == curtab)
break;
}
break;
}
break;
case '$': /* '$' - last line */
++cmd;
lnum = curbuf->b_ml.ml_line_count;
switch (addr_type) {
case ADDR_LINES:
lnum = curbuf->b_ml.ml_line_count;
break;
case ADDR_WINDOWS:
lnum = 0;
for (wp = firstwin; wp != NULL; wp = wp->w_next) {
lnum++;
}
break;
case ADDR_ARGUMENTS:
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_UNLOADED_BUFFERS:
lnum = lastbuf->b_fnum;
break;
case ADDR_TABS:
lnum = 0;
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
lnum++;
}
break;
}
break;
case '\'': /* ''' - mark */
@ -3132,6 +3285,10 @@ get_address (
cmd = NULL;
goto error;
}
if (addr_type != ADDR_LINES) {
EMSG(_(e_invaddr));
goto error;
}
if (skip)
++cmd;
else {
@ -3155,6 +3312,10 @@ get_address (
case '/':
case '?': /* '/' or '?' - search */
c = *cmd++;
if (addr_type != ADDR_LINES) {
EMSG(_(e_invaddr));
goto error;
}
if (skip) { /* skip "/pat/" */
cmd = skip_regexp(cmd, c, p_magic, NULL);
if (*cmd == c)
@ -3194,6 +3355,10 @@ get_address (
case '\\': /* "\?", "\/" or "\&", repeat search */
++cmd;
if (addr_type != ADDR_LINES) {
EMSG(_(e_invaddr));
goto error;
}
if (*cmd == '&')
i = RE_SUBST;
else if (*cmd == '?' || *cmd == '/')
@ -3233,8 +3398,37 @@ get_address (
if (*cmd != '-' && *cmd != '+' && !ascii_isdigit(*cmd))
break;
if (lnum == MAXLNUM)
lnum = curwin->w_cursor.lnum; /* "+1" is same as ".+1" */
if (lnum == MAXLNUM) {
switch (addr_type) {
case ADDR_LINES:
lnum = curwin->w_cursor.lnum; /* "+1" is same as ".+1" */
break;
case ADDR_WINDOWS:
lnum = 0;
for (wp = firstwin; wp != NULL; wp = wp->w_next) {
lnum++;
if (wp == curwin)
break;
}
break;
case ADDR_ARGUMENTS:
lnum = curwin->w_arg_idx + 1;
break;
case ADDR_LOADED_BUFFERS:
case ADDR_UNLOADED_BUFFERS:
lnum = curbuf->b_fnum;
break;
case ADDR_TABS:
lnum = 0;
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
lnum++;
if (tp == curtab)
break;
}
break;
}
}
if (ascii_isdigit(*cmd))
i = '+'; /* "number" is same as "+number" */
else
@ -3242,11 +3436,56 @@ get_address (
if (!ascii_isdigit(*cmd)) /* '+' is '+1', but '+0' is not '+1' */
n = 1;
else
n = getdigits_long(&cmd);
if (i == '-')
n = getdigits(&cmd);
if (addr_type == ADDR_LOADED_BUFFERS ||
addr_type == ADDR_UNLOADED_BUFFERS)
lnum = compute_buffer_local_count(addr_type, lnum, n);
else if (i == '-')
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;
}
c = 0;
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
c++;
if (lnum >= c)
lnum = c;
break;
case ADDR_WINDOWS:
if (lnum < 0) {
lnum = 0;
break;
}
c = 0;
for (wp = firstwin; wp != NULL; wp = wp->w_next)
c++;
if (lnum > c)
lnum = c;
break;
case ADDR_LOADED_BUFFERS:
case ADDR_UNLOADED_BUFFERS:
if (lnum < firstbuf->b_fnum) {
lnum = firstbuf->b_fnum;
break;
}
if (lnum > lastbuf->b_fnum)
lnum = lastbuf->b_fnum;
break;
}
}
} while (*cmd == '/' || *cmd == '?');
@ -5102,10 +5341,29 @@ static void ex_quit(exarg_T *eap)
text_locked_msg();
return;
}
win_T *wp;
buf_T *buf;
int wnr;
if (eap->addr_count > 0) {
wnr = eap->line2;
for (wp = firstwin; --wnr > 0;) {
if (wp->w_next == NULL)
break;
else
wp = wp->w_next;
}
buf = wp->w_buffer;
} else {
wp = curwin;
buf = curbuf;
}
apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
/* Refuse to quit when locked or when the buffer in the last window is
* being closed (can only happen in autocommands). */
if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing))
if (curbuf_locked() || (buf->b_nwindows == 1 && curbuf->b_closing))
return;
@ -5127,7 +5385,7 @@ static void ex_quit(exarg_T *eap)
getout(0);
}
/* close window; may free buffer */
win_close(curwin, !P_HID(curwin->w_buffer) || eap->forceit);
win_close(wp, !P_HID(wp->w_buffer) || eap->forceit);
}
}
@ -5174,12 +5432,24 @@ static void ex_quit_all(exarg_T *eap)
*/
static void ex_close(exarg_T *eap)
{
win_T *win;
int winnr = 0;
if (cmdwin_type != 0)
cmdwin_result = Ctrl_C;
else if (!text_locked()
&& !curbuf_locked()
)
ex_win_close(eap->forceit, curwin, NULL);
else if (!text_locked() && !curbuf_locked()) {
if (eap->addr_count == 0)
ex_win_close(eap->forceit, curwin, NULL);
else {
for (win = firstwin; win != NULL; win = win->w_next) {
winnr++;
if (winnr == eap->line2)
break;
}
if (win == NULL)
win = lastwin;
ex_win_close(eap->forceit, win, NULL);
}
}
}
/*
@ -5271,6 +5541,8 @@ static void ex_tabonly(exarg_T *eap)
else if (first_tabpage->tp_next == NULL)
MSG(_("Already only one tab page"));
else {
if (eap->addr_count > 0)
goto_tabpage(eap->line2);
/* Repeat this up to a 1000 times, because autocommands may mess
* up the lists. */
for (int done = 0; done < 1000; ++done) {
@ -5341,6 +5613,18 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
*/
static void ex_only(exarg_T *eap)
{
win_T *wp;
int wnr;
if (eap->addr_count > 0) {
wnr = eap->line2;
for (wp = firstwin; --wnr > 0;) {
if (wp->w_next == NULL)
break;
else
wp = wp->w_next;
}
win_goto(wp);
}
close_others(TRUE, eap->forceit);
}
@ -5357,13 +5641,26 @@ void ex_all(exarg_T *eap)
static void ex_hide(exarg_T *eap)
{
win_T *win;
int winnr = 0;
if (*eap->arg != NUL && check_nextcmd(eap->arg) == NULL)
eap->errmsg = e_invarg;
else {
/* ":hide" or ":hide | cmd": hide current window */
eap->nextcmd = check_nextcmd(eap->arg);
if (!eap->skip) {
win_close(curwin, FALSE); /* don't free buffer */
if (eap->addr_count == 0)
win_close(curwin, FALSE); /* don't free buffer */
else {
for (win = firstwin; win != NULL; win = win->w_next) {
winnr++;
if (winnr == eap->line2)
break;
}
if (win == NULL)
win = lastwin;
win_close(win, FALSE);
}
}
}
}
@ -6518,7 +6815,7 @@ static void ex_copymove(exarg_T *eap)
{
long n;
n = get_address(&eap->arg, FALSE, FALSE);
n = get_address(&eap->arg, eap->addr_type, FALSE, FALSE);
if (eap->arg == NULL) { /* error detected */
eap->nextcmd = NULL;
return;

View File

@ -29,7 +29,9 @@ SCRIPTS := test_autoformat_join.out \
test86.out test87.out test88.out \
test96.out \
test_listlbr.out \
test_breakindent.out
test_breakindent.out \
test_argument_count.out \
test_close_count.out
SCRIPTS_GUI := test16.out

View File

@ -0,0 +1,47 @@
Tests for :[count]argument! and :[count]argdelete vim: set ft=vim :
STARTTEST
:%argd
:argadd a b c d
:set hidden
:let buffers = []
:augroup TEST
:au BufEnter * call add(buffers, expand('%:t'))
:augroup END
:$argu
:$-argu
:-argu
:1argu
:+2argu
:augroup TEST
:au!
:augroup END
:let arglists = []
:.argd
:call add(arglists, argv())
:-argd
:call add(arglists, argv())
:$argd
:call add(arglists, argv())
:1arga c
:1arga b
:$argu
:+arga d
:$arga x
:call add(arglists, argv())
:$-10arga Y
:call add(arglists, argv())
:%argd
:call add(arglists, argv())
:arga a b c d e f
:2,$-argd
:call add(arglists, argv())
:e! test.out
:call append(0, buffers)
:let lnr = line('$')
:call append(lnr, map(copy(arglists), 'join(v:val, " ")'))
:w
:qa!
ENDTEST

View File

@ -0,0 +1,13 @@
d
c
b
a
c
a b d
a d
a
a b c d x
Y a b c d x
a f

View File

@ -0,0 +1,156 @@
Tests for :[count]close! and :[count]hide vim: set ft=vim :
STARTTEST
:let tests = []
:so tiny.vim
:for i in range(5)
:new
:endfor
:4wincmd w
:close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:$close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1wincmd w
:2close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1wincmd w
:new
:new
:2wincmd w
:-2close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:2wincmd w
:+1close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:e! test.out
:call append(0, map(copy(tests), 'join(v:val, " ")'))
:w
:only!
:b1
ENDTEST
STARTTEST
:let tests = []
:so tiny.vim
:for i in range(5)
:new
:endfor
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:4wincmd w
:.hide
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1hide
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:9hide
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1wincmd w
:2hide
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1wincmd w
:new
:new
:3wincmd w
:-hide
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:2wincmd w
:+hide
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:e! test.out
:call append(line('$'), map(copy(tests), 'join(v:val, " ")'))
Go
:w
:only!
:b1
ENDTEST
STARTTEST
:let tests = []
:so tiny.vim
:set hidden
:for i in range(5)
:new
:endfor
:1wincmd w
:$ hide
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:$-1 close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1wincmd w
:.+close!
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:e! test.out
:call append(line('$'), map(copy(tests), 'join(v:val, " ")'))
Go
:w
:only!
:b1
ENDTEST
STARTTEST
:let tests = []
:so tiny.vim
:set hidden
:for i in range(5)
:new
:endfor
:4wincmd w
c
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
1c
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
9c
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:1wincmd w
2c
:let buffers = []
:windo call add(buffers, bufnr('%'))
:call add(tests, buffers)
:only!
:e! test.out
:call append(line('$'), map(copy(tests), 'join(v:val, " ")'))
:w
:qa!
ENDTEST

View File

@ -0,0 +1,23 @@
6 5 4 2 1
5 4 2 1
5 4 2
5 2
7 5 2
7 5
13 12 11 10 9 1
13 12 11 9 1
12 11 9 1
12 11 9
12 9
15 12 9
15 12
20 19 18 17 16
20 19 18 16
20 18 16
25 24 23 21 1
24 23 21 1
24 23 21
24 21

View File

@ -151,14 +151,20 @@ newwindow:
case Ctrl_Q:
case 'q':
reset_VIsual_and_resel(); /* stop Visual mode */
do_cmdline_cmd((char_u *)"quit");
STRCPY(cbuf, "quit");
if (Prenum)
vim_snprintf((char *)cbuf + 4, sizeof(cbuf) - 5, "%ld", Prenum);
do_cmdline_cmd(cbuf);
break;
/* close current window */
case Ctrl_C:
case 'c':
reset_VIsual_and_resel(); /* stop Visual mode */
do_cmdline_cmd((char_u *)"close");
STRCPY(cbuf, "close");
if (Prenum)
vim_snprintf((char *)cbuf + 4, sizeof(cbuf) - 5, "%ld", Prenum);
do_cmdline_cmd(cbuf);
break;
/* close preview window */
@ -183,7 +189,10 @@ newwindow:
case Ctrl_O:
case 'o':
CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
do_cmdline_cmd((char_u *)"only");
STRCPY(cbuf, "only");
if (Prenum > 0)
vim_snprintf((char *)cbuf + 4, sizeof(cbuf) - 4, "%ld", Prenum);
do_cmdline_cmd(cbuf);
break;
/* cursor to next window with wrap around */