mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	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:
		@@ -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]tabe[dit]				*:tabe* *:tabedit* *:tabnew*
 | 
				
			||||||
:[count]tabnew
 | 
					:[count]tabnew
 | 
				
			||||||
		Open a new tab page with an empty window, after the current
 | 
							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]tabe[dit] [++opt] [+cmd] {file}
 | 
				
			||||||
:[count]tabnew [++opt] [+cmd] {file}
 | 
					:[count]tabnew [++opt] [+cmd] {file}
 | 
				
			||||||
		Open a new tab page and edit {file}, like with |:edit|.
 | 
							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*
 | 
					:[count]tabf[ind] [++opt] [+cmd] {file}			*:tabf* *:tabfind*
 | 
				
			||||||
		Open a new tab page and edit {file} in 'path', like with
 | 
							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
 | 
							{not available when the |+file_in_path| feature was disabled
 | 
				
			||||||
		at compile time}
 | 
							at compile time}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,12 +119,18 @@ something else.
 | 
				
			|||||||
		- When 'hidden' is not set, [!] is not used, a buffer has
 | 
							- When 'hidden' is not set, [!] is not used, a buffer has
 | 
				
			||||||
		  changes, and there is no other window on this buffer.
 | 
							  changes, and there is no other window on this buffer.
 | 
				
			||||||
		Changes to the buffer are not written and won't get lost, so
 | 
							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}
 | 
					:tabc[lose][!] {count}
 | 
				
			||||||
		Close tab page {count}.  Fails in the same way as `:tabclose`
 | 
							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* *:tabonly*
 | 
				
			||||||
:tabo[nly][!]	Close all other tab pages.
 | 
					:tabo[nly][!]	Close all other tab pages.
 | 
				
			||||||
		When the 'hidden' option is set, all buffers in closed windows
 | 
							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
 | 
							modified buffers are written.  Otherwise, windows that have
 | 
				
			||||||
		buffers that are modified are not removed, unless the [!] is
 | 
							buffers that are modified are not removed, unless the [!] is
 | 
				
			||||||
		given, then they become hidden.  But modified buffers are
 | 
							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:
 | 
					SWITCHING TO ANOTHER TAB PAGE:
 | 
				
			||||||
@@ -176,8 +200,15 @@ REORDERING TAB PAGES:
 | 
				
			|||||||
:[N]tabm[ove]
 | 
					:[N]tabm[ove]
 | 
				
			||||||
		Move the current tab page to after tab page N.  Use zero to
 | 
							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
 | 
							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]
 | 
				
			||||||
:tabm[ove] -[N]
 | 
					:tabm[ove] -[N]
 | 
				
			||||||
		Move the current tab page N places to the right (with +) or to
 | 
							Move the current tab page N places to the right (with +) or to
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -263,28 +263,54 @@ left of the Vim window.
 | 
				
			|||||||
Closing a window
 | 
					Closing a window
 | 
				
			||||||
----------------
 | 
					----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:q[uit]
 | 
				
			||||||
 | 
					:{count}q[uit]
 | 
				
			||||||
CTRL-W q						*CTRL-W_q*
 | 
					CTRL-W q						*CTRL-W_q*
 | 
				
			||||||
CTRL-W CTRL-Q						*CTRL-W_CTRL-Q*
 | 
					CTRL-W CTRL-Q						*CTRL-W_CTRL-Q*
 | 
				
			||||||
:q[uit]		Quit current window.  When quitting the last window (not
 | 
							Without {count}: Quit the current window. If {count} is
 | 
				
			||||||
		counting a help window), exit Vim.
 | 
							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
 | 
							When 'hidden' is set, and there is only one window for the
 | 
				
			||||||
		current buffer, it becomes hidden.
 | 
							current buffer, it becomes hidden. When 'hidden' is not set,
 | 
				
			||||||
		When 'hidden' is not set, and there is only one window for the
 | 
							and there is only one window for the current buffer, and the
 | 
				
			||||||
		current buffer, and the buffer was changed, the command fails.
 | 
							buffer was changed, the command fails.
 | 
				
			||||||
		(Note: CTRL-Q does not work on all terminals)
 | 
							(Note: CTRL-Q does not work on all terminals).
 | 
				
			||||||
 | 
							If [count] is greater than the last window number the last
 | 
				
			||||||
:q[uit]!	Quit current window.  If this was the last window for a buffer,
 | 
							window will be closed: >
 | 
				
			||||||
		any changes to that buffer are lost.  When quitting the last
 | 
							    :1quit  " quit the first window
 | 
				
			||||||
		window (not counting help windows), exit Vim.  The contents of
 | 
							    :$quit  " quit the last window
 | 
				
			||||||
		the buffer are lost, even when 'hidden' is set.
 | 
							    :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*
 | 
					CTRL-W c					*CTRL-W_c* *:clo* *:close*
 | 
				
			||||||
:clo[se][!]	Close current window.  When the 'hidden' option is set, or
 | 
							Without {count}: Close the current window. If given close the
 | 
				
			||||||
		when the buffer was changed and the [!] is used, the buffer
 | 
							{count} window.
 | 
				
			||||||
		becomes hidden (unless there is another window editing it).
 | 
					
 | 
				
			||||||
 | 
							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
 | 
							When there is only one window in the current tab page and
 | 
				
			||||||
		there is another tab page, this closes the current tab page.
 | 
							there is another tab page, this closes the current tab page.
 | 
				
			||||||
		|tab-page|.
 | 
							|tab-page|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		This command fails when:			*E444*
 | 
							This command fails when:			*E444*
 | 
				
			||||||
		- There is only one window on the screen.
 | 
							- There is only one window on the screen.
 | 
				
			||||||
		- When 'hidden' is not set, [!] is not used, the buffer has
 | 
							- 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
 | 
							window, but that does not work, because the CTRL-C cancels the
 | 
				
			||||||
		command.
 | 
							command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							*:hide*
 | 
					                                                                *:hide*
 | 
				
			||||||
:hid[e]		Quit current window, unless it is the last window on the
 | 
					:hid[e]
 | 
				
			||||||
		screen.  The buffer becomes hidden (unless there is another
 | 
					:{count}hid[e]
 | 
				
			||||||
		window editing it or 'bufhidden' is "unload" or "delete").
 | 
							Quit the current window, unless it is the last window on the
 | 
				
			||||||
		If the window is the last one in the current tab page the tab
 | 
							screen. For {count} see |:quit|.
 | 
				
			||||||
		page is closed. |tab-page|
 | 
					
 | 
				
			||||||
 | 
							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.
 | 
							The value of 'hidden' is irrelevant for this command.
 | 
				
			||||||
		Changes to the buffer are not written and won't get lost, so
 | 
							Changes to the buffer are not written and won't get lost, so
 | 
				
			||||||
		this is a "safe" command.
 | 
							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.
 | 
							'hidden' is restored after {cmd} has been executed.
 | 
				
			||||||
		Example: >
 | 
							Example: >
 | 
				
			||||||
		    :hide edit Makefile
 | 
							    :hide edit Makefile
 | 
				
			||||||
<		This will edit "Makefile", and hide the current buffer if it
 | 
					<		This will edit "Makefile", and hide the current buffer if it
 | 
				
			||||||
		has any changes.
 | 
							has any changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:on[ly][!]
 | 
				
			||||||
 | 
					:{count}on[ly][!]
 | 
				
			||||||
CTRL-W o						*CTRL-W_o* *E445*
 | 
					CTRL-W o						*CTRL-W_o* *E445*
 | 
				
			||||||
CTRL-W CTRL-O					*CTRL-W_CTRL-O* *:on* *:only*
 | 
					CTRL-W CTRL-O					*CTRL-W_CTRL-O* *:on* *:only*
 | 
				
			||||||
:on[ly][!]	Make the current window the only one on the screen.  All other
 | 
							Make the current window the only one on the screen. All other
 | 
				
			||||||
		windows are closed.
 | 
							windows are closed. For {count} see |:quit|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		When the 'hidden' option is set, all buffers in closed windows
 | 
							When the 'hidden' option is set, all buffers in closed windows
 | 
				
			||||||
		become hidden.
 | 
							become hidden.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		When 'hidden' is not set, and the 'autowrite' option is set,
 | 
							When 'hidden' is not set, and the 'autowrite' option is set,
 | 
				
			||||||
		modified buffers are written.  Otherwise, windows that have
 | 
							modified buffers are written.  Otherwise, windows that have
 | 
				
			||||||
		buffers that are modified are not removed, unless the [!] is
 | 
							buffers that are modified are not removed, unless the [!] is
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,8 +67,9 @@ for i, cmd in ipairs(defs) do
 | 
				
			|||||||
  [%s] = {
 | 
					  [%s] = {
 | 
				
			||||||
    .cmd_name = (char_u *) "%s",
 | 
					    .cmd_name = (char_u *) "%s",
 | 
				
			||||||
    .cmd_func = &%s,
 | 
					    .cmd_func = &%s,
 | 
				
			||||||
    .cmd_argt = %u
 | 
					    .cmd_argt = %uL,
 | 
				
			||||||
  }]], enumname, cmd.command, cmd.func, cmd.flags))
 | 
					    .cmd_addr_type = %i
 | 
				
			||||||
 | 
					  }]], enumname, cmd.command, cmd.func, cmd.flags, cmd.addr_type))
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
defsfile:write([[
 | 
					defsfile:write([[
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -71,6 +71,14 @@
 | 
				
			|||||||
#define WORD1   (EXTRA | NOSPC) /* one extra word allowed */
 | 
					#define WORD1   (EXTRA | NOSPC) /* one extra word allowed */
 | 
				
			||||||
#define FILE1   (FILES | NOSPC) /* 1 file allowed, defaults to current file */
 | 
					#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;
 | 
					typedef struct exarg exarg_T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* behavior for bad character, "++bad=" argument */
 | 
					/* behavior for bad character, "++bad=" argument */
 | 
				
			||||||
@@ -87,6 +95,7 @@ typedef struct cmdname {
 | 
				
			|||||||
  char_u *cmd_name;    ///< Name of the command.
 | 
					  char_u *cmd_name;    ///< Name of the command.
 | 
				
			||||||
  ex_func_T cmd_func;  ///< Function with implementation of this command.
 | 
					  ex_func_T cmd_func;  ///< Function with implementation of this command.
 | 
				
			||||||
  uint32_t cmd_argt;     ///< Relevant flags from the declared above.
 | 
					  uint32_t cmd_argt;     ///< Relevant flags from the declared above.
 | 
				
			||||||
 | 
					  int cmd_addr_type;     ///< Flag for address type
 | 
				
			||||||
} CommandDefinition;
 | 
					} CommandDefinition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Arguments used for Ex commands.
 | 
					/// Arguments used for Ex commands.
 | 
				
			||||||
@@ -102,6 +111,7 @@ struct exarg {
 | 
				
			|||||||
  int addr_count;               ///< the number of addresses given
 | 
					  int addr_count;               ///< the number of addresses given
 | 
				
			||||||
  linenr_T line1;               ///< the first line number
 | 
					  linenr_T line1;               ///< the first line number
 | 
				
			||||||
  linenr_T line2;               ///< the second line number or count
 | 
					  linenr_T line2;               ///< the second line number or count
 | 
				
			||||||
 | 
					  int addr_type;                ///< type of the count/range
 | 
				
			||||||
  int flags;                    ///< extra flags after count: EXFLAG_
 | 
					  int flags;                    ///< extra flags after count: EXFLAG_
 | 
				
			||||||
  char_u      *do_ecmd_cmd;     ///< +command arg to be used in edited file
 | 
					  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
 | 
					  linenr_T do_ecmd_lnum;        ///< the line number in an edited file
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1065,6 +1065,33 @@ void * getline_cookie(LineGetter fgetline,
 | 
				
			|||||||
  return cp;
 | 
					  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.
 | 
					 * Execute one Ex command.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -1072,10 +1099,11 @@ void * getline_cookie(LineGetter fgetline,
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * 1. skip comment lines and leading space
 | 
					 * 1. skip comment lines and leading space
 | 
				
			||||||
 * 2. handle command modifiers
 | 
					 * 2. handle command modifiers
 | 
				
			||||||
 * 3. parse range
 | 
					 * 3. skip over the range to find the command
 | 
				
			||||||
 * 4. parse command
 | 
					 * 4. parse the range
 | 
				
			||||||
 * 5. parse arguments
 | 
					 * 5. parse the command
 | 
				
			||||||
 * 6. switch on command name
 | 
					 * 6. parse arguments
 | 
				
			||||||
 | 
					 * 7. switch on command name
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Note: "fgetline" can be NULL.
 | 
					 * Note: "fgetline" can be NULL.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -1100,6 +1128,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
 | 
				
			|||||||
  int did_sandbox = FALSE;
 | 
					  int did_sandbox = FALSE;
 | 
				
			||||||
  cmdmod_T save_cmdmod;
 | 
					  cmdmod_T save_cmdmod;
 | 
				
			||||||
  int ni;                                       /* set when Not Implemented */
 | 
					  int ni;                                       /* set when Not Implemented */
 | 
				
			||||||
 | 
					  win_T *wp;
 | 
				
			||||||
 | 
					  tabpage_T *tp;
 | 
				
			||||||
 | 
					  char_u *cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  memset(&ea, 0, sizeof(ea));
 | 
					  memset(&ea, 0, sizeof(ea));
 | 
				
			||||||
  ea.line1 = 1;
 | 
					  ea.line1 = 1;
 | 
				
			||||||
@@ -1132,7 +1163,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
 | 
				
			|||||||
  ea.cmd = *cmdlinep;
 | 
					  ea.cmd = *cmdlinep;
 | 
				
			||||||
  for (;; ) {
 | 
					  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 == ':')
 | 
					    while (*ea.cmd == ' ' || *ea.cmd == '\t' || *ea.cmd == ':')
 | 
				
			||||||
      ++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;
 | 
					    p = ea.cmd;
 | 
				
			||||||
    if (ascii_isdigit(*ea.cmd))
 | 
					    if (ascii_isdigit(*ea.cmd))
 | 
				
			||||||
@@ -1319,8 +1350,18 @@ static char_u * do_one_cmd(char_u **cmdlinep,
 | 
				
			|||||||
    (void)do_intthrow(cstack);
 | 
					    (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:
 | 
					   * where 'addr' is:
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
@@ -1336,25 +1377,82 @@ static char_u * do_one_cmd(char_u **cmdlinep,
 | 
				
			|||||||
   * is equal to the lower.
 | 
					   * 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 */
 | 
					  /* repeat for all ',' or ';' separated addresses */
 | 
				
			||||||
  for (;; ) {
 | 
					  for (;; ) {
 | 
				
			||||||
    ea.line1 = ea.line2;
 | 
					    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);
 | 
					    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 */
 | 
					    if (ea.cmd == NULL)                     /* error detected */
 | 
				
			||||||
      goto doend;
 | 
					      goto doend;
 | 
				
			||||||
    if (lnum == MAXLNUM) {
 | 
					    if (lnum == MAXLNUM) {
 | 
				
			||||||
      if (*ea.cmd == '%') {                 /* '%' - all lines */
 | 
					      if (*ea.cmd == '%') {                 /* '%' - all lines */
 | 
				
			||||||
        ++ea.cmd;
 | 
					        ++ea.cmd;
 | 
				
			||||||
        ea.line1 = 1;
 | 
					        switch (ea.addr_type) {
 | 
				
			||||||
        ea.line2 = curbuf->b_ml.ml_line_count;
 | 
					          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;
 | 
					        ++ea.addr_count;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      /* '*' - visual area */
 | 
					      /* '*' - visual area */
 | 
				
			||||||
      else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) {
 | 
					      else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) {
 | 
				
			||||||
        pos_T       *fp;
 | 
					        pos_T       *fp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ea.addr_type != ADDR_LINES) {
 | 
				
			||||||
 | 
					          errormsg = (char_u *)_(e_invrange);
 | 
				
			||||||
 | 
					          goto doend;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ++ea.cmd;
 | 
					        ++ea.cmd;
 | 
				
			||||||
        if (!ea.skip) {
 | 
					        if (!ea.skip) {
 | 
				
			||||||
          fp = getmark('<', FALSE);
 | 
					          fp = getmark('<', FALSE);
 | 
				
			||||||
@@ -1392,7 +1490,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
 | 
				
			|||||||
  check_cursor_lnum();
 | 
					  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;
 | 
					    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
 | 
					  // If this looks like an undefined user command and there are CmdUndefined
 | 
				
			||||||
  // autocommands defined, trigger the matching autocommands.
 | 
					  // autocommands defined, trigger the matching autocommands.
 | 
				
			||||||
  if (p != NULL && ea.cmdidx == CMD_SIZE && !ea.skip
 | 
					  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;
 | 
					    ea.forceit = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * 5. parse arguments
 | 
					   * 6. Parse arguments.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  if (!IS_USER_CMDIDX(ea.cmdidx)) {
 | 
					  if (!IS_USER_CMDIDX(ea.cmdidx)) {
 | 
				
			||||||
    ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt;
 | 
					    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.
 | 
					   * The "ea" structure holds the arguments that can be used.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@@ -3098,12 +3193,11 @@ skip_range (
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * Return MAXLNUM when no Ex address was found.
 | 
					 * Return MAXLNUM when no Ex address was found.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static linenr_T 
 | 
					static linenr_T get_address(char_u **ptr,
 | 
				
			||||||
get_address (
 | 
					                            int addr_type,  // flag: one of ADDR_LINES, ...
 | 
				
			||||||
    char_u **ptr,
 | 
					                            int skip,  // only skip the address, don't use it
 | 
				
			||||||
    int skip,                   /* only skip the address, don't use it */
 | 
					                            int to_other_file  // flag: may jump to other file
 | 
				
			||||||
    int to_other_file              /* flag: may jump to other file */
 | 
					                            )
 | 
				
			||||||
)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int c;
 | 
					  int c;
 | 
				
			||||||
  int i;
 | 
					  int i;
 | 
				
			||||||
@@ -3112,6 +3206,9 @@ get_address (
 | 
				
			|||||||
  pos_T pos;
 | 
					  pos_T pos;
 | 
				
			||||||
  pos_T       *fp;
 | 
					  pos_T       *fp;
 | 
				
			||||||
  linenr_T lnum;
 | 
					  linenr_T lnum;
 | 
				
			||||||
 | 
					  win_T *wp;
 | 
				
			||||||
 | 
					  tabpage_T *tp;
 | 
				
			||||||
 | 
					  buf_T *buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cmd = skipwhite(*ptr);
 | 
					  cmd = skipwhite(*ptr);
 | 
				
			||||||
  lnum = MAXLNUM;
 | 
					  lnum = MAXLNUM;
 | 
				
			||||||
@@ -3119,12 +3216,68 @@ get_address (
 | 
				
			|||||||
    switch (*cmd) {
 | 
					    switch (*cmd) {
 | 
				
			||||||
    case '.':                               /* '.' - Cursor position */
 | 
					    case '.':                               /* '.' - Cursor position */
 | 
				
			||||||
      ++cmd;
 | 
					      ++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;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case '$':                               /* '$' - last line */
 | 
					    case '$':                               /* '$' - last line */
 | 
				
			||||||
      ++cmd;
 | 
					      ++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;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case '\'':                              /* ''' - mark */
 | 
					    case '\'':                              /* ''' - mark */
 | 
				
			||||||
@@ -3132,6 +3285,10 @@ get_address (
 | 
				
			|||||||
        cmd = NULL;
 | 
					        cmd = NULL;
 | 
				
			||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      if (addr_type != ADDR_LINES) {
 | 
				
			||||||
 | 
					        EMSG(_(e_invaddr));
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (skip)
 | 
					      if (skip)
 | 
				
			||||||
        ++cmd;
 | 
					        ++cmd;
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
@@ -3155,6 +3312,10 @@ get_address (
 | 
				
			|||||||
    case '/':
 | 
					    case '/':
 | 
				
			||||||
    case '?':                           /* '/' or '?' - search */
 | 
					    case '?':                           /* '/' or '?' - search */
 | 
				
			||||||
      c = *cmd++;
 | 
					      c = *cmd++;
 | 
				
			||||||
 | 
					      if (addr_type != ADDR_LINES) {
 | 
				
			||||||
 | 
					        EMSG(_(e_invaddr));
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (skip) {                       /* skip "/pat/" */
 | 
					      if (skip) {                       /* skip "/pat/" */
 | 
				
			||||||
        cmd = skip_regexp(cmd, c, p_magic, NULL);
 | 
					        cmd = skip_regexp(cmd, c, p_magic, NULL);
 | 
				
			||||||
        if (*cmd == c)
 | 
					        if (*cmd == c)
 | 
				
			||||||
@@ -3194,6 +3355,10 @@ get_address (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    case '\\':                      /* "\?", "\/" or "\&", repeat search */
 | 
					    case '\\':                      /* "\?", "\/" or "\&", repeat search */
 | 
				
			||||||
      ++cmd;
 | 
					      ++cmd;
 | 
				
			||||||
 | 
					      if (addr_type != ADDR_LINES) {
 | 
				
			||||||
 | 
					        EMSG(_(e_invaddr));
 | 
				
			||||||
 | 
					        goto error;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      if (*cmd == '&')
 | 
					      if (*cmd == '&')
 | 
				
			||||||
        i = RE_SUBST;
 | 
					        i = RE_SUBST;
 | 
				
			||||||
      else if (*cmd == '?' || *cmd == '/')
 | 
					      else if (*cmd == '?' || *cmd == '/')
 | 
				
			||||||
@@ -3233,8 +3398,37 @@ get_address (
 | 
				
			|||||||
      if (*cmd != '-' && *cmd != '+' && !ascii_isdigit(*cmd))
 | 
					      if (*cmd != '-' && *cmd != '+' && !ascii_isdigit(*cmd))
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (lnum == MAXLNUM)
 | 
					      if (lnum == MAXLNUM) {
 | 
				
			||||||
        lnum = curwin->w_cursor.lnum;           /* "+1" is same as ".+1" */
 | 
					        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))
 | 
					      if (ascii_isdigit(*cmd))
 | 
				
			||||||
        i = '+';                        /* "number" is same as "+number" */
 | 
					        i = '+';                        /* "number" is same as "+number" */
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
@@ -3242,11 +3436,56 @@ get_address (
 | 
				
			|||||||
      if (!ascii_isdigit(*cmd))           /* '+' is '+1', but '+0' is not '+1' */
 | 
					      if (!ascii_isdigit(*cmd))           /* '+' is '+1', but '+0' is not '+1' */
 | 
				
			||||||
        n = 1;
 | 
					        n = 1;
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        n = getdigits_long(&cmd);
 | 
					        n = getdigits(&cmd);
 | 
				
			||||||
      if (i == '-')
 | 
					      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;
 | 
					        lnum -= n;
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        lnum += n;
 | 
					        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 == '?');
 | 
					  } while (*cmd == '/' || *cmd == '?');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5102,10 +5341,29 @@ static void ex_quit(exarg_T *eap)
 | 
				
			|||||||
    text_locked_msg();
 | 
					    text_locked_msg();
 | 
				
			||||||
    return;
 | 
					    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);
 | 
					  apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
 | 
				
			||||||
  /* Refuse to quit when locked or when the buffer in the last window is
 | 
					  /* Refuse to quit when locked or when the buffer in the last window is
 | 
				
			||||||
   * being closed (can only happen in autocommands). */
 | 
					   * 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;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5127,7 +5385,7 @@ static void ex_quit(exarg_T *eap)
 | 
				
			|||||||
      getout(0);
 | 
					      getout(0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* close window; may free buffer */
 | 
					    /* 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)
 | 
					static void ex_close(exarg_T *eap)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  win_T *win;
 | 
				
			||||||
 | 
					  int winnr = 0;
 | 
				
			||||||
  if (cmdwin_type != 0)
 | 
					  if (cmdwin_type != 0)
 | 
				
			||||||
    cmdwin_result = Ctrl_C;
 | 
					    cmdwin_result = Ctrl_C;
 | 
				
			||||||
  else if (!text_locked()
 | 
					  else if (!text_locked() && !curbuf_locked()) {
 | 
				
			||||||
           && !curbuf_locked()
 | 
					    if (eap->addr_count == 0)
 | 
				
			||||||
           )
 | 
					      ex_win_close(eap->forceit, curwin, NULL);
 | 
				
			||||||
    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)
 | 
					  else if (first_tabpage->tp_next == NULL)
 | 
				
			||||||
    MSG(_("Already only one tab page"));
 | 
					    MSG(_("Already only one tab page"));
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
 | 
					    if (eap->addr_count > 0)
 | 
				
			||||||
 | 
					      goto_tabpage(eap->line2);
 | 
				
			||||||
    /* Repeat this up to a 1000 times, because autocommands may mess
 | 
					    /* Repeat this up to a 1000 times, because autocommands may mess
 | 
				
			||||||
     * up the lists. */
 | 
					     * up the lists. */
 | 
				
			||||||
    for (int done = 0; done < 1000; ++done) {
 | 
					    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)
 | 
					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);
 | 
					  close_others(TRUE, eap->forceit);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5357,13 +5641,26 @@ void ex_all(exarg_T *eap)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void ex_hide(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)
 | 
					  if (*eap->arg != NUL && check_nextcmd(eap->arg) == NULL)
 | 
				
			||||||
    eap->errmsg = e_invarg;
 | 
					    eap->errmsg = e_invarg;
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    /* ":hide" or ":hide | cmd": hide current window */
 | 
					    /* ":hide" or ":hide | cmd": hide current window */
 | 
				
			||||||
    eap->nextcmd = check_nextcmd(eap->arg);
 | 
					    eap->nextcmd = check_nextcmd(eap->arg);
 | 
				
			||||||
    if (!eap->skip) {
 | 
					    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;
 | 
					  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 */
 | 
					  if (eap->arg == NULL) {           /* error detected */
 | 
				
			||||||
    eap->nextcmd = NULL;
 | 
					    eap->nextcmd = NULL;
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,9 @@ SCRIPTS := test_autoformat_join.out                                    \
 | 
				
			|||||||
           test86.out  test87.out  test88.out                          \
 | 
					           test86.out  test87.out  test88.out                          \
 | 
				
			||||||
           test96.out                                                  \
 | 
					           test96.out                                                  \
 | 
				
			||||||
           test_listlbr.out                                            \
 | 
					           test_listlbr.out                                            \
 | 
				
			||||||
           test_breakindent.out
 | 
					           test_breakindent.out                                        \
 | 
				
			||||||
 | 
					           test_argument_count.out                                     \
 | 
				
			||||||
 | 
					           test_close_count.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SCRIPTS_GUI := test16.out
 | 
					SCRIPTS_GUI := test16.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								src/nvim/testdir/test_argument_count.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/nvim/testdir/test_argument_count.in
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/nvim/testdir/test_argument_count.ok
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/nvim/testdir/test_argument_count.ok
									
									
									
									
									
										Normal 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
 | 
				
			||||||
							
								
								
									
										156
									
								
								src/nvim/testdir/test_close_count.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								src/nvim/testdir/test_close_count.in
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/nvim/testdir/test_close_count.ok
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/nvim/testdir/test_close_count.ok
									
									
									
									
									
										Normal 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
 | 
				
			||||||
@@ -151,14 +151,20 @@ newwindow:
 | 
				
			|||||||
  case Ctrl_Q:
 | 
					  case Ctrl_Q:
 | 
				
			||||||
  case 'q':
 | 
					  case 'q':
 | 
				
			||||||
    reset_VIsual_and_resel();                   /* stop Visual mode */
 | 
					    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;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* close current window */
 | 
					  /* close current window */
 | 
				
			||||||
  case Ctrl_C:
 | 
					  case Ctrl_C:
 | 
				
			||||||
  case 'c':
 | 
					  case 'c':
 | 
				
			||||||
    reset_VIsual_and_resel();                   /* stop Visual mode */
 | 
					    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;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* close preview window */
 | 
					  /* close preview window */
 | 
				
			||||||
@@ -183,7 +189,10 @@ newwindow:
 | 
				
			|||||||
  case Ctrl_O:
 | 
					  case Ctrl_O:
 | 
				
			||||||
  case 'o':
 | 
					  case 'o':
 | 
				
			||||||
    CHECK_CMDWIN reset_VIsual_and_resel();      /* stop Visual mode */
 | 
					    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;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* cursor to next window with wrap around */
 | 
					  /* cursor to next window with wrap around */
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user