mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	Merge #8247 'server: introduce --listen'
This commit is contained in:
		
							
								
								
									
										40
									
								
								man/nvim.1
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								man/nvim.1
									
									
									
									
									
								
							@@ -25,7 +25,7 @@ To enter commands in
 | 
				
			|||||||
type a colon
 | 
					type a colon
 | 
				
			||||||
.Pq Sq \&:
 | 
					.Pq Sq \&:
 | 
				
			||||||
which is also used in this manual to denote commands.
 | 
					which is also used in this manual to denote commands.
 | 
				
			||||||
For more information, consult the on-line help system with the
 | 
					For more information, consult the online help system with the
 | 
				
			||||||
.Ic :help
 | 
					.Ic :help
 | 
				
			||||||
command.
 | 
					command.
 | 
				
			||||||
.Bl -tag -width Fl
 | 
					.Bl -tag -width Fl
 | 
				
			||||||
@@ -329,6 +329,9 @@ Implies
 | 
				
			|||||||
.Fl -headless .
 | 
					.Fl -headless .
 | 
				
			||||||
.It Fl -headless
 | 
					.It Fl -headless
 | 
				
			||||||
Do not start a user interface.
 | 
					Do not start a user interface.
 | 
				
			||||||
 | 
					.Fl -listen .
 | 
				
			||||||
 | 
					.It Fl -listen Ar address
 | 
				
			||||||
 | 
					Start RPC server on this pipe or TCP socket.
 | 
				
			||||||
.It Fl h , -help
 | 
					.It Fl h , -help
 | 
				
			||||||
Print usage information and exit.
 | 
					Print usage information and exit.
 | 
				
			||||||
.It Fl v , -version
 | 
					.It Fl v , -version
 | 
				
			||||||
@@ -337,12 +340,12 @@ Print version information and exit.
 | 
				
			|||||||
.Sh ENVIRONMENT
 | 
					.Sh ENVIRONMENT
 | 
				
			||||||
.Bl -tag -width Fl
 | 
					.Bl -tag -width Fl
 | 
				
			||||||
.It Ev VIM
 | 
					.It Ev VIM
 | 
				
			||||||
Used to locate various user files, such as the user's init.vim.
 | 
					Used to locate various user files, such as init.vim.
 | 
				
			||||||
.It Ev VIMRUNTIME
 | 
					.It Ev VIMRUNTIME
 | 
				
			||||||
Used to locate run time files, such as on-line documentation and
 | 
					Used to locate runtime files, such as online documentation and
 | 
				
			||||||
syntax highlighting definitions.
 | 
					syntax highlighting definitions.
 | 
				
			||||||
.It Ev XDG_CONFIG_HOME
 | 
					.It Ev XDG_CONFIG_HOME
 | 
				
			||||||
Path to use for the user-local configuration directory, see
 | 
					Path to the user-local configuration directory, see
 | 
				
			||||||
.Sx FILES .
 | 
					.Sx FILES .
 | 
				
			||||||
Defaults to
 | 
					Defaults to
 | 
				
			||||||
.Pa ~/.config
 | 
					.Pa ~/.config
 | 
				
			||||||
@@ -356,7 +359,7 @@ Defaults to
 | 
				
			|||||||
.Pa ~/.local/share
 | 
					.Pa ~/.local/share
 | 
				
			||||||
if not set.
 | 
					if not set.
 | 
				
			||||||
.It Ev VIMINIT
 | 
					.It Ev VIMINIT
 | 
				
			||||||
A string of Ex commands to be executed at startup.
 | 
					Ex commands to be executed at startup.
 | 
				
			||||||
For example, the command to quit is
 | 
					For example, the command to quit is
 | 
				
			||||||
.Ic :q ,
 | 
					.Ic :q ,
 | 
				
			||||||
so to have
 | 
					so to have
 | 
				
			||||||
@@ -375,41 +378,32 @@ command.
 | 
				
			|||||||
.Sh FILES
 | 
					.Sh FILES
 | 
				
			||||||
.Bl -tag -width "~/.config/nvim/init.vim"
 | 
					.Bl -tag -width "~/.config/nvim/init.vim"
 | 
				
			||||||
.It Pa ~/.config/nvim/init.vim
 | 
					.It Pa ~/.config/nvim/init.vim
 | 
				
			||||||
The user-local
 | 
					User-local
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
configuration file.
 | 
					configuration file.
 | 
				
			||||||
See
 | 
					 | 
				
			||||||
.Ev XDG_CONFIG_HOME
 | 
					 | 
				
			||||||
above.
 | 
					 | 
				
			||||||
.It Pa ~/.config/nvim
 | 
					.It Pa ~/.config/nvim
 | 
				
			||||||
The user-local
 | 
					User-local
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
configuration directory.
 | 
					configuration directory.
 | 
				
			||||||
See
 | 
					See also
 | 
				
			||||||
.Ev XDG_CONFIG_HOME
 | 
					.Ev XDG_CONFIG_HOME .
 | 
				
			||||||
above.
 | 
					 | 
				
			||||||
.It Pa $VIM/sysinit.vim
 | 
					.It Pa $VIM/sysinit.vim
 | 
				
			||||||
The system-global
 | 
					System-global
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
configuration file.
 | 
					configuration file.
 | 
				
			||||||
.It Pa /usr/local/share/nvim
 | 
					.It Pa /usr/local/share/nvim
 | 
				
			||||||
The system-global
 | 
					System-global
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
runtime directory.
 | 
					runtime directory.
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Sh AUTHORS
 | 
					.Sh AUTHORS
 | 
				
			||||||
.Nm
 | 
					Nvim was started by
 | 
				
			||||||
was started by
 | 
					.An Thiago de Arruda .
 | 
				
			||||||
.An Thiago de Arruda ,
 | 
					 | 
				
			||||||
with a lot of help from others.
 | 
					 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
Most of Vim was written by
 | 
					Most of Vim was written by
 | 
				
			||||||
.An -nosplit
 | 
					.An -nosplit
 | 
				
			||||||
.An Bram Moolenaar ,
 | 
					.An Bram Moolenaar .
 | 
				
			||||||
with a lot of help from others.
 | 
					 | 
				
			||||||
See
 | 
					See
 | 
				
			||||||
.Ic :help credits .
 | 
					.Ic :help credits .
 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
Vim is based on Stevie, worked on by
 | 
					Vim is based on Stevie, worked on by
 | 
				
			||||||
.An Tim Thompson ,
 | 
					.An Tim Thompson ,
 | 
				
			||||||
.An Tony Andrews ,
 | 
					.An Tony Andrews ,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,10 @@ Commands ~
 | 
				
			|||||||
*:wv*
 | 
					*:wv*
 | 
				
			||||||
*:wviminfo*		Deprecated alias to |:wshada| command.
 | 
					*:wviminfo*		Deprecated alias to |:wshada| command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Environment Variables ~
 | 
				
			||||||
 | 
					*$NVIM_LISTEN_ADDRESS*	Deprecated in favor of |--listen|.  If both are given,
 | 
				
			||||||
 | 
								$NVIM_LISTEN_ADDRESS is ignored.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Events ~
 | 
					Events ~
 | 
				
			||||||
*EncodingChanged*	Never fired; 'encoding' is always "utf-8".
 | 
					*EncodingChanged*	Never fired; 'encoding' is always "utf-8".
 | 
				
			||||||
*FileEncoding*		Never fired; equivalent to |EncodingChanged|.
 | 
					*FileEncoding*		Never fired; equivalent to |EncodingChanged|.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1788,9 +1788,9 @@ v:scrollstart	String describing the script or function that caused the
 | 
				
			|||||||
		hit-enter prompt.
 | 
							hit-enter prompt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					*v:servername* *servername-variable*
 | 
										*v:servername* *servername-variable*
 | 
				
			||||||
					*$NVIM_LISTEN_ADDRESS*
 | 
					v:servername	Primary listen-address of the current Nvim instance, the first
 | 
				
			||||||
v:servername	Default Nvim server address. Equivalent to
 | 
							item returned by |serverlist()|.  Can be set by |--listen| or
 | 
				
			||||||
		|$NVIM_LISTEN_ADDRESS| on startup. |serverstop()|
 | 
							|$NVIM_LISTEN_ADDRESS| at startup. |serverstart()| |serverstop()|
 | 
				
			||||||
		Read-only.
 | 
							Read-only.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -6638,15 +6638,11 @@ server2client({clientid}, {string})			*server2client()*
 | 
				
			|||||||
			:echo server2client(expand("<client>"), "HELLO")
 | 
								:echo server2client(expand("<client>"), "HELLO")
 | 
				
			||||||
<
 | 
					<
 | 
				
			||||||
serverlist()						*serverlist()*
 | 
					serverlist()						*serverlist()*
 | 
				
			||||||
		Returns a list of available server names in a list.
 | 
							Returns a list of server addresses, or empty if all servers
 | 
				
			||||||
		When there are no servers an empty string is returned.
 | 
							were stopped. |serverstart()| |serverstop()|
 | 
				
			||||||
		Example: >
 | 
							Example: >
 | 
				
			||||||
			:echo serverlist()
 | 
								:echo serverlist()
 | 
				
			||||||
<						{Nvim} *--serverlist*
 | 
					
 | 
				
			||||||
		The Vim command-line option `--serverlist` was removed from
 | 
					 | 
				
			||||||
		Nvim, but it can be imitated: >
 | 
					 | 
				
			||||||
			nvim --cmd "echo serverlist()" --cmd "q"
 | 
					 | 
				
			||||||
<
 | 
					 | 
				
			||||||
serverstart([{address}])				*serverstart()*
 | 
					serverstart([{address}])				*serverstart()*
 | 
				
			||||||
		Opens a socket or named pipe at {address} and listens for
 | 
							Opens a socket or named pipe at {address} and listens for
 | 
				
			||||||
		|RPC| messages. Clients can send |API| commands to the address
 | 
							|RPC| messages. Clients can send |API| commands to the address
 | 
				
			||||||
@@ -6674,13 +6670,9 @@ serverstart([{address}])				*serverstart()*
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
< 		|$NVIM_LISTEN_ADDRESS| is set to {address} if not already set.
 | 
					< 		|$NVIM_LISTEN_ADDRESS| is set to {address} if not already set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							*--servername*
 | 
					 | 
				
			||||||
		The Vim command-line option `--servername` can be imitated: >
 | 
					 | 
				
			||||||
			nvim --cmd "let g:server_addr = serverstart('foo')"
 | 
					 | 
				
			||||||
<
 | 
					 | 
				
			||||||
serverstop({address})					*serverstop()*
 | 
					serverstop({address})					*serverstop()*
 | 
				
			||||||
		Closes the pipe or socket at {address}. Does nothing if
 | 
							Closes the pipe or socket at {address}.
 | 
				
			||||||
		{address} is empty or invalid.
 | 
							Returns TRUE if {address} is valid, else FALSE.
 | 
				
			||||||
		If |$NVIM_LISTEN_ADDRESS| is stopped it is unset.
 | 
							If |$NVIM_LISTEN_ADDRESS| is stopped it is unset.
 | 
				
			||||||
		If |v:servername| is stopped it is set to the next available
 | 
							If |v:servername| is stopped it is set to the next available
 | 
				
			||||||
		address returned by |serverlist()|.
 | 
							address returned by |serverlist()|.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,9 +70,8 @@ An rpc socket is automatically created with each instance. The socket
 | 
				
			|||||||
 location is stored in |v:servername|. By default this is a named pipe
 | 
					 location is stored in |v:servername|. By default this is a named pipe
 | 
				
			||||||
with an automatically generated address. See |XXX|.
 | 
					with an automatically generated address. See |XXX|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To make Nvim listen on a TCP/IP socket instead, set the
 | 
					To make Nvim listen on a TCP/IP socket instead, specify |--listen|: >
 | 
				
			||||||
   |$NVIM_LISTEN_ADDRESS| environment variable before starting Nvim: >
 | 
					    nvim --listen 127.0.0.1:6666
 | 
				
			||||||
        NVIM_LISTEN_ADDRESS=127.0.0.1:6666 nvim
 | 
					 | 
				
			||||||
<Also, more sockets and named pipes can be listened on using |serverstart()|.
 | 
					<Also, more sockets and named pipes can be listened on using |serverstart()|.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Note that localhost TCP sockets are generally less secure than named pipes,
 | 
					Note that localhost TCP sockets are generally less secure than named pipes,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -355,6 +355,10 @@ argument.
 | 
				
			|||||||
                instead.
 | 
					                instead.
 | 
				
			||||||
		See also |silent-mode|, which does start a (limited) UI.
 | 
							See also |silent-mode|, which does start a (limited) UI.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--listen {addr}						*--listen*
 | 
				
			||||||
 | 
					                Start |RPC| server on socket or TCP address {addr}. Sets the
 | 
				
			||||||
 | 
					                primary listen address |v:servername| to {addr}. |serverstart()|
 | 
				
			||||||
 | 
					
 | 
				
			||||||
==============================================================================
 | 
					==============================================================================
 | 
				
			||||||
2. Initialization				*initialization* *startup*
 | 
					2. Initialization				*initialization* *startup*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,50 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env expect
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if {$argc < 2} {
 | 
					 | 
				
			||||||
  puts "Need commands for running the tests and for starting nvim"
 | 
					 | 
				
			||||||
  exit 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set timeout 60
 | 
					 | 
				
			||||||
set run_tests [split [lindex $argv 0] " "]
 | 
					 | 
				
			||||||
set run_nvim [split [lindex $argv 1] " "]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# don't echo to stdout
 | 
					 | 
				
			||||||
log_user 0
 | 
					 | 
				
			||||||
# set NVIM_LISTEN_ADDRESS, so nvim will listen on a known socket
 | 
					 | 
				
			||||||
set env(NVIM_LISTEN_ADDRESS) "/tmp/nvim-[exec date +%s%N].sock"
 | 
					 | 
				
			||||||
# start nvim
 | 
					 | 
				
			||||||
spawn {*}$run_nvim
 | 
					 | 
				
			||||||
# save the job descriptor
 | 
					 | 
				
			||||||
set nvim_id $spawn_id
 | 
					 | 
				
			||||||
# Reset function that can be invoked by test runners to put nvim in a cleaner
 | 
					 | 
				
			||||||
# state
 | 
					 | 
				
			||||||
send {
 | 
					 | 
				
			||||||
:echo "read"."y"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
# wait until nvim is ready
 | 
					 | 
				
			||||||
expect "ready"
 | 
					 | 
				
			||||||
# run tests
 | 
					 | 
				
			||||||
spawn {*}$run_tests
 | 
					 | 
				
			||||||
set tests_id $spawn_id
 | 
					 | 
				
			||||||
set status 1
 | 
					 | 
				
			||||||
# listen for test output in the background
 | 
					 | 
				
			||||||
expect_background {
 | 
					 | 
				
			||||||
  * {
 | 
					 | 
				
			||||||
    # show test output to the user
 | 
					 | 
				
			||||||
    send_user -- $expect_out(buffer)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  eof {
 | 
					 | 
				
			||||||
    # collect the exit status code
 | 
					 | 
				
			||||||
    set spawn_id $tests_id
 | 
					 | 
				
			||||||
    catch wait result
 | 
					 | 
				
			||||||
    set status [lindex $result 3]
 | 
					 | 
				
			||||||
    set spawn_id $nvim_id
 | 
					 | 
				
			||||||
    # quit nvim
 | 
					 | 
				
			||||||
    send ":qa!\r"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
# switch back nvim and wait until it exits 
 | 
					 | 
				
			||||||
set spawn_id $nvim_id
 | 
					 | 
				
			||||||
expect eof
 | 
					 | 
				
			||||||
exit $status
 | 
					 | 
				
			||||||
@@ -14403,8 +14403,11 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rettv->v_type = VAR_NUMBER;
 | 
				
			||||||
 | 
					  rettv->vval.v_number = 0;
 | 
				
			||||||
  if (argvars[0].vval.v_string) {
 | 
					  if (argvars[0].vval.v_string) {
 | 
				
			||||||
    server_stop((char *) argvars[0].vval.v_string);
 | 
					    bool rv = server_stop((char *)argvars[0].vval.v_string);
 | 
				
			||||||
 | 
					    rettv->vval.v_number = (rv ? 1 : 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6975,12 +6975,10 @@ do_exedit (
 | 
				
			|||||||
  ex_no_reprint = TRUE;
 | 
					  ex_no_reprint = TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/// ":gui" and ":gvim" when there is no GUI.
 | 
				
			||||||
 * ":gui" and ":gvim" when there is no GUI.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void ex_nogui(exarg_T *eap)
 | 
					static void ex_nogui(exarg_T *eap)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  eap->errmsg = e_nogvim;
 | 
					  eap->errmsg = (char_u *)N_("E25: Nvim does not have a built-in GUI");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1070,7 +1070,6 @@ EXTERN char_u e_nesting[] INIT(= N_("E22: Scripts nested too deep"));
 | 
				
			|||||||
EXTERN char_u e_noalt[] INIT(= N_("E23: No alternate file"));
 | 
					EXTERN char_u e_noalt[] INIT(= N_("E23: No alternate file"));
 | 
				
			||||||
EXTERN char_u e_noabbr[] INIT(= N_("E24: No such abbreviation"));
 | 
					EXTERN char_u e_noabbr[] INIT(= N_("E24: No such abbreviation"));
 | 
				
			||||||
EXTERN char_u e_nobang[] INIT(= N_("E477: No ! allowed"));
 | 
					EXTERN char_u e_nobang[] INIT(= N_("E477: No ! allowed"));
 | 
				
			||||||
EXTERN char_u e_nogvim[] INIT(= N_("E25: Nvim does not have a built-in GUI"));
 | 
					 | 
				
			||||||
EXTERN char_u e_nogroup[] INIT(= N_("E28: No such highlight group name: %s"));
 | 
					EXTERN char_u e_nogroup[] INIT(= N_("E28: No such highlight group name: %s"));
 | 
				
			||||||
EXTERN char_u e_noinstext[] INIT(= N_("E29: No inserted text yet"));
 | 
					EXTERN char_u e_noinstext[] INIT(= N_("E29: No inserted text yet"));
 | 
				
			||||||
EXTERN char_u e_nolastcmd[] INIT(= N_("E30: No previous command line"));
 | 
					EXTERN char_u e_nolastcmd[] INIT(= N_("E30: No previous command line"));
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										108
									
								
								src/nvim/main.c
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								src/nvim/main.c
									
									
									
									
									
								
							@@ -72,30 +72,30 @@
 | 
				
			|||||||
# include "nvim/os/pty_process_unix.h"
 | 
					# include "nvim/os/pty_process_unix.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Maximum number of commands from + or -c arguments. */
 | 
					// Maximum number of commands from + or -c arguments.
 | 
				
			||||||
#define MAX_ARG_CMDS 10
 | 
					#define MAX_ARG_CMDS 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* values for "window_layout" */
 | 
					// values for "window_layout"
 | 
				
			||||||
#define WIN_HOR     1       /* "-o" horizontally split windows */
 | 
					#define WIN_HOR     1       // "-o" horizontally split windows
 | 
				
			||||||
#define WIN_VER     2       /* "-O" vertically split windows */
 | 
					#define WIN_VER     2       // "-O" vertically split windows
 | 
				
			||||||
#define WIN_TABS    3       /* "-p" windows on tab pages */
 | 
					#define WIN_TABS    3       // "-p" windows on tab pages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Struct for various parameters passed between main() and other functions. */
 | 
					// Struct for various parameters passed between main() and other functions.
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  int argc;
 | 
					  int argc;
 | 
				
			||||||
  char        **argv;
 | 
					  char        **argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  char *use_vimrc;                           // vimrc from -u argument
 | 
					  char *use_vimrc;                           // vimrc from -u argument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int n_commands;                            /* no. of commands from + or -c */
 | 
					  int n_commands;                            // no. of commands from + or -c
 | 
				
			||||||
  char *commands[MAX_ARG_CMDS];              // commands from + or -c arg
 | 
					  char *commands[MAX_ARG_CMDS];              // commands from + or -c arg
 | 
				
			||||||
  char_u cmds_tofree[MAX_ARG_CMDS];          /* commands that need free() */
 | 
					  char_u cmds_tofree[MAX_ARG_CMDS];          // commands that need free()
 | 
				
			||||||
  int n_pre_commands;                        /* no. of commands from --cmd */
 | 
					  int n_pre_commands;                        // no. of commands from --cmd
 | 
				
			||||||
  char *pre_commands[MAX_ARG_CMDS];          // commands from --cmd argument
 | 
					  char *pre_commands[MAX_ARG_CMDS];          // commands from --cmd argument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int edit_type;                        /* type of editing to do */
 | 
					  int edit_type;                        // type of editing to do
 | 
				
			||||||
  char_u      *tagname;                 /* tag from -t argument */
 | 
					  char_u      *tagname;                 // tag from -t argument
 | 
				
			||||||
  char_u      *use_ef;                  /* 'errorfile' from -q argument */
 | 
					  char_u      *use_ef;                  // 'errorfile' from -q argument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int want_full_screen;
 | 
					  int want_full_screen;
 | 
				
			||||||
  bool input_isatty;                    // stdin is a terminal
 | 
					  bool input_isatty;                    // stdin is a terminal
 | 
				
			||||||
@@ -103,13 +103,15 @@ typedef struct {
 | 
				
			|||||||
  bool err_isatty;                      // stderr is a terminal
 | 
					  bool err_isatty;                      // stderr is a terminal
 | 
				
			||||||
  int no_swap_file;                     // "-n" argument used
 | 
					  int no_swap_file;                     // "-n" argument used
 | 
				
			||||||
  int use_debug_break_level;
 | 
					  int use_debug_break_level;
 | 
				
			||||||
  int window_count;                     /* number of windows to use */
 | 
					  int window_count;                     // number of windows to use
 | 
				
			||||||
  int window_layout;                    /* 0, WIN_HOR, WIN_VER or WIN_TABS */
 | 
					  int window_layout;                    // 0, WIN_HOR, WIN_VER or WIN_TABS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(UNIX)
 | 
					#if !defined(UNIX)
 | 
				
			||||||
  int literal;                          /* don't expand file names */
 | 
					  int literal;                          // don't expand file names
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  int diff_mode;                        /* start with 'diff' set */
 | 
					  int diff_mode;                        // start with 'diff' set
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char *listen_addr;                    // --listen {address}
 | 
				
			||||||
} mparm_T;
 | 
					} mparm_T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Values for edit_type. */
 | 
					/* Values for edit_type. */
 | 
				
			||||||
@@ -150,7 +152,6 @@ void event_init(void)
 | 
				
			|||||||
  signal_init();
 | 
					  signal_init();
 | 
				
			||||||
  // finish mspgack-rpc initialization
 | 
					  // finish mspgack-rpc initialization
 | 
				
			||||||
  channel_init();
 | 
					  channel_init();
 | 
				
			||||||
  server_init();
 | 
					 | 
				
			||||||
  terminal_init();
 | 
					  terminal_init();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -241,9 +242,8 @@ int main(int argc, char **argv)
 | 
				
			|||||||
  char_u *cwd = NULL;     // current workding dir on startup
 | 
					  char_u *cwd = NULL;     // current workding dir on startup
 | 
				
			||||||
  time_init();
 | 
					  time_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Many variables are in "params" so that we can pass them to invoked
 | 
					  // Many variables are in `params` so that we can pass them around easily.
 | 
				
			||||||
   * functions without a lot of arguments.  "argc" and "argv" are also
 | 
					  // `argc` and `argv` are also copied, so that they can be changed.
 | 
				
			||||||
   * copied, so that they can be changed. */
 | 
					 | 
				
			||||||
  init_params(¶ms, argc, argv);
 | 
					  init_params(¶ms, argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init_startuptime(¶ms);
 | 
					  init_startuptime(¶ms);
 | 
				
			||||||
@@ -254,11 +254,10 @@ int main(int argc, char **argv)
 | 
				
			|||||||
  check_and_set_isatty(¶ms);
 | 
					  check_and_set_isatty(¶ms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  event_init();
 | 
					  event_init();
 | 
				
			||||||
  /*
 | 
					  // Process the command line arguments.  File names are put in the global
 | 
				
			||||||
   * Process the command line arguments.  File names are put in the global
 | 
					  // argument list "global_alist".
 | 
				
			||||||
   * argument list "global_alist".
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  command_line_scan(¶ms);
 | 
					  command_line_scan(¶ms);
 | 
				
			||||||
 | 
					  server_init(params.listen_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (GARGCOUNT > 0) {
 | 
					  if (GARGCOUNT > 0) {
 | 
				
			||||||
    fname = get_fname(¶ms, cwd);
 | 
					    fname = get_fname(¶ms, cwd);
 | 
				
			||||||
@@ -819,6 +818,9 @@ static void command_line_scan(mparm_T *parmp)
 | 
				
			|||||||
            if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) {
 | 
					            if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) {
 | 
				
			||||||
              abort();
 | 
					              abort();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					          } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) {
 | 
				
			||||||
 | 
					            want_argument = true;
 | 
				
			||||||
 | 
					            argv_idx += 6;
 | 
				
			||||||
          } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
 | 
					          } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
 | 
				
			||||||
#if !defined(UNIX)
 | 
					#if !defined(UNIX)
 | 
				
			||||||
            parmp->literal = TRUE;
 | 
					            parmp->literal = TRUE;
 | 
				
			||||||
@@ -864,10 +866,6 @@ static void command_line_scan(mparm_T *parmp)
 | 
				
			|||||||
        case 'f':                 /* "-f"  GUI: run in foreground. */
 | 
					        case 'f':                 /* "-f"  GUI: run in foreground. */
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case 'g':                 /* "-g" start GUI */
 | 
					 | 
				
			||||||
          main_start_gui();
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        case 'F': {  // "-F" start in Farsi mode: rl + fkmap set.
 | 
					        case 'F': {  // "-F" start in Farsi mode: rl + fkmap set.
 | 
				
			||||||
          p_fkmap = true;
 | 
					          p_fkmap = true;
 | 
				
			||||||
          set_option_value("rl", 1L, NULL, 0);
 | 
					          set_option_value("rl", 1L, NULL, 0);
 | 
				
			||||||
@@ -906,18 +904,8 @@ static void command_line_scan(mparm_T *parmp)
 | 
				
			|||||||
          parmp->no_swap_file = TRUE;
 | 
					          parmp->no_swap_file = TRUE;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case 'p':                 /* "-p[N]" open N tab pages */
 | 
					        case 'p':                 // "-p[N]" open N tab pages
 | 
				
			||||||
#ifdef TARGET_API_MAC_OSX
 | 
					          // default is 0: open window for each file
 | 
				
			||||||
          /* For some reason on MacOS X, an argument like:
 | 
					 | 
				
			||||||
             -psn_0_10223617 is passed in when invoke from Finder
 | 
					 | 
				
			||||||
             or with the 'open' command */
 | 
					 | 
				
			||||||
          if (argv[0][argv_idx] == 's') {
 | 
					 | 
				
			||||||
            argv_idx = -1;           /* bypass full -psn */
 | 
					 | 
				
			||||||
            main_start_gui();
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
          /* default is 0: open window for each file */
 | 
					 | 
				
			||||||
          parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
 | 
					          parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
 | 
				
			||||||
          parmp->window_layout = WIN_TABS;
 | 
					          parmp->window_layout = WIN_TABS;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
@@ -1030,15 +1018,12 @@ static void command_line_scan(mparm_T *parmp)
 | 
				
			|||||||
          mainerr(err_opt_unknown, argv[0]);
 | 
					          mainerr(err_opt_unknown, argv[0]);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /*
 | 
					      // Handle option arguments with argument.
 | 
				
			||||||
       * Handle option arguments with argument.
 | 
					 | 
				
			||||||
       */
 | 
					 | 
				
			||||||
      if (want_argument) {
 | 
					      if (want_argument) {
 | 
				
			||||||
        /*
 | 
					        // Check for garbage immediately after the option letter.
 | 
				
			||||||
         * Check for garbage immediately after the option letter.
 | 
					        if (argv[0][argv_idx] != NUL) {
 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (argv[0][argv_idx] != NUL)
 | 
					 | 
				
			||||||
          mainerr(err_opt_garbage, argv[0]);
 | 
					          mainerr(err_opt_garbage, argv[0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        --argc;
 | 
					        --argc;
 | 
				
			||||||
        if (argc < 1 && c != 'S')          /* -S has an optional argument */
 | 
					        if (argc < 1 && c != 'S')          /* -S has an optional argument */
 | 
				
			||||||
@@ -1077,13 +1062,17 @@ static void command_line_scan(mparm_T *parmp)
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          case '-':
 | 
					          case '-':
 | 
				
			||||||
            if (argv[-1][2] == 'c') {
 | 
					            if (strequal(argv[-1], "--cmd")) {
 | 
				
			||||||
              /* "--cmd {command}" execute command */
 | 
					              // "--cmd {command}" execute command
 | 
				
			||||||
              if (parmp->n_pre_commands >= MAX_ARG_CMDS)
 | 
					              if (parmp->n_pre_commands >= MAX_ARG_CMDS) {
 | 
				
			||||||
                mainerr(err_extra_cmd, NULL);
 | 
					                mainerr(err_extra_cmd, NULL);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
              parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
 | 
					              parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
 | 
				
			||||||
 | 
					            } else if (strequal(argv[-1], "--listen")) {
 | 
				
			||||||
 | 
					              // "--listen {address}"
 | 
				
			||||||
 | 
					              parmp->listen_addr = argv[0];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            /* "--startuptime <file>" already handled */
 | 
					            // "--startuptime <file>" already handled
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          case 'q':               /* "-q {errorfile}" QuickFix mode */
 | 
					          case 'q':               /* "-q {errorfile}" QuickFix mode */
 | 
				
			||||||
@@ -1224,11 +1213,10 @@ static void init_params(mparm_T *paramp, int argc, char **argv)
 | 
				
			|||||||
  paramp->want_full_screen = true;
 | 
					  paramp->want_full_screen = true;
 | 
				
			||||||
  paramp->use_debug_break_level = -1;
 | 
					  paramp->use_debug_break_level = -1;
 | 
				
			||||||
  paramp->window_count = -1;
 | 
					  paramp->window_count = -1;
 | 
				
			||||||
 | 
					  paramp->listen_addr = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/// Initialize global startuptime file if "--startuptime" passed as an argument.
 | 
				
			||||||
 * Initialize global startuptime file if "--startuptime" passed as an argument.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void init_startuptime(mparm_T *paramp)
 | 
					static void init_startuptime(mparm_T *paramp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  for (int i = 1; i < paramp->argc; i++) {
 | 
					  for (int i = 1; i < paramp->argc; i++) {
 | 
				
			||||||
@@ -1834,17 +1822,6 @@ static void source_startup_scripts(const mparm_T *const parmp)
 | 
				
			|||||||
  TIME_MSG("sourcing vimrc file(s)");
 | 
					  TIME_MSG("sourcing vimrc file(s)");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Setup to start using the GUI.  Exit with an error when not available.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void main_start_gui(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  mch_errmsg(_(e_nogvim));
 | 
					 | 
				
			||||||
  mch_errmsg("\n");
 | 
					 | 
				
			||||||
  mch_exit(2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Get an environment variable, and execute it as Ex commands.
 | 
					/// Get an environment variable, and execute it as Ex commands.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// @param env         environment variable to execute
 | 
					/// @param env         environment variable to execute
 | 
				
			||||||
@@ -1968,6 +1945,7 @@ static void usage(void)
 | 
				
			|||||||
  mch_msg(_("  --api-info            Write msgpack-encoded API metadata to stdout\n"));
 | 
					  mch_msg(_("  --api-info            Write msgpack-encoded API metadata to stdout\n"));
 | 
				
			||||||
  mch_msg(_("  --embed               Use stdin/stdout as a msgpack-rpc channel\n"));
 | 
					  mch_msg(_("  --embed               Use stdin/stdout as a msgpack-rpc channel\n"));
 | 
				
			||||||
  mch_msg(_("  --headless            Don't start a user interface\n"));
 | 
					  mch_msg(_("  --headless            Don't start a user interface\n"));
 | 
				
			||||||
 | 
					  mch_msg(_("  --listen <address>    Start RPC server at this address\n"));
 | 
				
			||||||
#if !defined(UNIX)
 | 
					#if !defined(UNIX)
 | 
				
			||||||
  mch_msg(_("  --literal             Don't expand wildcards\n"));
 | 
					  mch_msg(_("  --literal             Don't expand wildcards\n"));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,26 +32,27 @@ static garray_T watchers = GA_EMPTY_INIT_VALUE;
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Initializes the module
 | 
					/// Initializes the module
 | 
				
			||||||
bool server_init(void)
 | 
					bool server_init(const char *listen_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  ga_init(&watchers, sizeof(SocketWatcher *), 1);
 | 
					  ga_init(&watchers, sizeof(SocketWatcher *), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool must_free = false;
 | 
					  // $NVIM_LISTEN_ADDRESS
 | 
				
			||||||
  const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
 | 
					  const char *env_addr = os_getenv(LISTEN_ADDRESS_ENV_VAR);
 | 
				
			||||||
  if (listen_address == NULL) {
 | 
					  int rv = listen_addr == NULL ? 1 : server_start(listen_addr);
 | 
				
			||||||
    must_free = true;
 | 
					
 | 
				
			||||||
    listen_address = server_address_new();
 | 
					  if (0 != rv) {
 | 
				
			||||||
 | 
					    rv = env_addr == NULL ? 1 : server_start(env_addr);
 | 
				
			||||||
 | 
					    if (0 != rv) {
 | 
				
			||||||
 | 
					      listen_addr = server_address_new();
 | 
				
			||||||
 | 
					      if (listen_addr == NULL) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      rv = server_start(listen_addr);
 | 
				
			||||||
 | 
					      xfree((char *)listen_addr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!listen_address) {
 | 
					  return rv == 0;
 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool ok = (server_start(listen_address) == 0);
 | 
					 | 
				
			||||||
  if (must_free) {
 | 
					 | 
				
			||||||
    xfree((char *) listen_address);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return ok;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Teardown a single server
 | 
					/// Teardown a single server
 | 
				
			||||||
@@ -120,8 +121,8 @@ bool server_owns_pipe_address(const char *path)
 | 
				
			|||||||
/// @param endpoint Address of the server. Either a 'ip:[port]' string or an
 | 
					/// @param endpoint Address of the server. Either a 'ip:[port]' string or an
 | 
				
			||||||
///                 arbitrary identifier (trimmed to 256 bytes) for the Unix
 | 
					///                 arbitrary identifier (trimmed to 256 bytes) for the Unix
 | 
				
			||||||
///                 socket or named pipe.
 | 
					///                 socket or named pipe.
 | 
				
			||||||
/// @returns 0 on success, 1 on a regular error, and negative errno
 | 
					/// @returns 0: success, 1: validation error, 2: already listening,
 | 
				
			||||||
///          on failure to bind or listen.
 | 
					///          -errno: failed to bind or listen.
 | 
				
			||||||
int server_start(const char *endpoint)
 | 
					int server_start(const char *endpoint)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (endpoint == NULL || endpoint[0] == '\0') {
 | 
					  if (endpoint == NULL || endpoint[0] == '\0') {
 | 
				
			||||||
@@ -145,7 +146,7 @@ int server_start(const char *endpoint)
 | 
				
			|||||||
        uv_freeaddrinfo(watcher->uv.tcp.addrinfo);
 | 
					        uv_freeaddrinfo(watcher->uv.tcp.addrinfo);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      socket_watcher_close(watcher, free_server);
 | 
					      socket_watcher_close(watcher, free_server);
 | 
				
			||||||
      return 1;
 | 
					      return 2;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -177,7 +178,7 @@ int server_start(const char *endpoint)
 | 
				
			|||||||
/// Stops listening on the address specified by `endpoint`.
 | 
					/// Stops listening on the address specified by `endpoint`.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// @param endpoint Address of the server.
 | 
					/// @param endpoint Address of the server.
 | 
				
			||||||
void server_stop(char *endpoint)
 | 
					bool server_stop(char *endpoint)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SocketWatcher *watcher;
 | 
					  SocketWatcher *watcher;
 | 
				
			||||||
  bool watcher_found = false;
 | 
					  bool watcher_found = false;
 | 
				
			||||||
@@ -196,8 +197,8 @@ void server_stop(char *endpoint)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!watcher_found) {
 | 
					  if (!watcher_found) {
 | 
				
			||||||
    ELOG("Not listening on %s", addr);
 | 
					    WLOG("Not listening on %s", addr);
 | 
				
			||||||
    return;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Unset $NVIM_LISTEN_ADDRESS if it is the stopped address.
 | 
					  // Unset $NVIM_LISTEN_ADDRESS if it is the stopped address.
 | 
				
			||||||
@@ -219,6 +220,8 @@ void server_stop(char *endpoint)
 | 
				
			|||||||
  if (STRCMP(addr, get_vim_var_str(VV_SEND_SERVER)) == 0) {
 | 
					  if (STRCMP(addr, get_vim_var_str(VV_SEND_SERVER)) == 0) {
 | 
				
			||||||
    set_vservername(&watchers);
 | 
					    set_vservername(&watchers);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Returns an allocated array of server addresses.
 | 
					/// Returns an allocated array of server addresses.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,31 +1,40 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
local helpers = require('test.functional.helpers')(after_each)
 | 
					local helpers = require('test.functional.helpers')(after_each)
 | 
				
			||||||
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
 | 
					local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
 | 
				
			||||||
local command = helpers.command
 | 
					local command = helpers.command
 | 
				
			||||||
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
 | 
					local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
 | 
				
			||||||
local os_name = helpers.os_name
 | 
					local iswin = helpers.iswin
 | 
				
			||||||
 | 
					local ok = helpers.ok
 | 
				
			||||||
 | 
					local matches = helpers.matches
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function clear_serverlist()
 | 
					local function clear_serverlist()
 | 
				
			||||||
    for _, server in pairs(funcs.serverlist()) do
 | 
					  for _, server in pairs(funcs.serverlist()) do
 | 
				
			||||||
      funcs.serverstop(server)
 | 
					    funcs.serverstop(server)
 | 
				
			||||||
    end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('serverstart(), serverstop()', function()
 | 
					describe('server', function()
 | 
				
			||||||
  before_each(clear)
 | 
					  before_each(clear)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('sets $NVIM_LISTEN_ADDRESS on first invocation', function()
 | 
					  it('serverstart() sets $NVIM_LISTEN_ADDRESS on first invocation', function()
 | 
				
			||||||
    -- Unset $NVIM_LISTEN_ADDRESS
 | 
					    -- Unset $NVIM_LISTEN_ADDRESS
 | 
				
			||||||
    command('let $NVIM_LISTEN_ADDRESS = ""')
 | 
					    command('let $NVIM_LISTEN_ADDRESS = ""')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local s = eval('serverstart()')
 | 
					    local s = eval('serverstart()')
 | 
				
			||||||
    assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
 | 
					    assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
 | 
				
			||||||
    eq(s, eval('$NVIM_LISTEN_ADDRESS'))
 | 
					    eq(s, eval('$NVIM_LISTEN_ADDRESS'))
 | 
				
			||||||
    command("call serverstop('"..s.."')")
 | 
					    eq(1, eval("serverstop('"..s.."')"))
 | 
				
			||||||
    eq('', eval('$NVIM_LISTEN_ADDRESS'))
 | 
					    eq('', eval('$NVIM_LISTEN_ADDRESS'))
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('sets v:servername _only_ on nvim startup unless all servers are stopped',
 | 
					  it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function()
 | 
				
			||||||
 | 
					    clear({env={NVIM_LISTEN_ADDRESS='.'}})
 | 
				
			||||||
 | 
					    eq('.', eval('$NVIM_LISTEN_ADDRESS'))
 | 
				
			||||||
 | 
					    local servers = funcs.serverlist()
 | 
				
			||||||
 | 
					    eq(1, #servers)
 | 
				
			||||||
 | 
					    ok(string.len(servers[1]) > 4)  -- Like /tmp/nvim…/… or \\.\pipe\…
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('sets v:servername at startup or if all servers were stopped',
 | 
				
			||||||
  function()
 | 
					  function()
 | 
				
			||||||
    local initial_server = meths.get_vvar('servername')
 | 
					    local initial_server = meths.get_vvar('servername')
 | 
				
			||||||
    assert(initial_server ~= nil and initial_server:len() > 0,
 | 
					    assert(initial_server ~= nil and initial_server:len() > 0,
 | 
				
			||||||
@@ -38,24 +47,23 @@ describe('serverstart(), serverstop()', function()
 | 
				
			|||||||
    neq(initial_server, s)
 | 
					    neq(initial_server, s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    -- serverstop() does _not_ modify v:servername...
 | 
					    -- serverstop() does _not_ modify v:servername...
 | 
				
			||||||
    funcs.serverstop(s)
 | 
					    eq(1, funcs.serverstop(s))
 | 
				
			||||||
    eq(initial_server, meths.get_vvar('servername'))
 | 
					    eq(initial_server, meths.get_vvar('servername'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    -- ...unless we stop _all_ servers.
 | 
					    -- ...unless we stop _all_ servers.
 | 
				
			||||||
    funcs.serverstop(funcs.serverlist()[1])
 | 
					    eq(1, funcs.serverstop(funcs.serverlist()[1]))
 | 
				
			||||||
    eq('', meths.get_vvar('servername'))
 | 
					    eq('', meths.get_vvar('servername'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    -- v:servername will take the next available server.
 | 
					    -- v:servername will take the next available server.
 | 
				
			||||||
    local servername = (os_name() == 'windows'
 | 
					    local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
 | 
				
			||||||
                        and [[\\.\pipe\Xtest-functional-server-pipe]]
 | 
					                                or 'Xtest-functional-server-socket')
 | 
				
			||||||
                        or 'Xtest-functional-server-socket')
 | 
					 | 
				
			||||||
    funcs.serverstart(servername)
 | 
					    funcs.serverstart(servername)
 | 
				
			||||||
    eq(servername, meths.get_vvar('servername'))
 | 
					    eq(servername, meths.get_vvar('servername'))
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('serverstop() ignores invalid input', function()
 | 
					  it('serverstop() returns false for invalid input', function()
 | 
				
			||||||
    command("call serverstop('')")
 | 
					    eq(0, eval("serverstop('')"))
 | 
				
			||||||
    command("call serverstop('bogus-socket-name')")
 | 
					    eq(0, eval("serverstop('bogus-socket-name')"))
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('parses endpoints correctly', function()
 | 
					  it('parses endpoints correctly', function()
 | 
				
			||||||
@@ -96,17 +104,13 @@ describe('serverstart(), serverstop()', function()
 | 
				
			|||||||
    funcs.serverstart('127.0.0.1:65536')  -- invalid port
 | 
					    funcs.serverstart('127.0.0.1:65536')  -- invalid port
 | 
				
			||||||
    eq({}, funcs.serverlist())
 | 
					    eq({}, funcs.serverlist())
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
end)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('serverlist()', function()
 | 
					  it('serverlist() returns the list of servers', function()
 | 
				
			||||||
  before_each(clear)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('returns the list of servers', function()
 | 
					 | 
				
			||||||
    -- There should already be at least one server.
 | 
					    -- There should already be at least one server.
 | 
				
			||||||
    local n = eval('len(serverlist())')
 | 
					    local n = eval('len(serverlist())')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    -- Add a few
 | 
					    -- Add some servers.
 | 
				
			||||||
    local servs = (os_name() == 'windows'
 | 
					    local servs = (iswin()
 | 
				
			||||||
      and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
 | 
					      and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
 | 
				
			||||||
      or  { [[Xtest-pipe0934]], [[Xtest-pipe4324]] })
 | 
					      or  { [[Xtest-pipe0934]], [[Xtest-pipe4324]] })
 | 
				
			||||||
    for _, s in ipairs(servs) do
 | 
					    for _, s in ipairs(servs) do
 | 
				
			||||||
@@ -120,9 +124,31 @@ describe('serverlist()', function()
 | 
				
			|||||||
    -- The new servers should be at the end of the list.
 | 
					    -- The new servers should be at the end of the list.
 | 
				
			||||||
    for i = 1, #servs do
 | 
					    for i = 1, #servs do
 | 
				
			||||||
      eq(servs[i], new_servs[i + n])
 | 
					      eq(servs[i], new_servs[i + n])
 | 
				
			||||||
      command("call serverstop('"..servs[i].."')")
 | 
					      eq(1, eval("serverstop('"..servs[i].."')"))
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    -- After serverstop() the servers should NOT be in the list.
 | 
					    -- After serverstop() the servers should NOT be in the list.
 | 
				
			||||||
    eq(n, eval('len(serverlist())'))
 | 
					    eq(n, eval('len(serverlist())'))
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
end)
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('startup --listen', function()
 | 
				
			||||||
 | 
					  it('validates', function()
 | 
				
			||||||
 | 
					    clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    local cmd = { unpack(helpers.nvim_argv) }
 | 
				
			||||||
 | 
					    table.insert(cmd, '--listen')
 | 
				
			||||||
 | 
					    matches('nvim.*: Argument missing after: "%-%-listen"', funcs.system(cmd))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cmd = { unpack(helpers.nvim_argv) }
 | 
				
			||||||
 | 
					    table.insert(cmd, '--listen2')
 | 
				
			||||||
 | 
					    matches('nvim.*: Garbage after option argument: "%-%-listen2"', funcs.system(cmd))
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
 | 
				
			||||||
 | 
					    local addr = (iswin() and [[\\.\pipe\Xtest-listen-pipe]]
 | 
				
			||||||
 | 
					                          or 'Xtest-listen-pipe')
 | 
				
			||||||
 | 
					    clear({ env={ NVIM_LISTEN_ADDRESS='Xtest-env-pipe' },
 | 
				
			||||||
 | 
					            args={ '--listen', addr } })
 | 
				
			||||||
 | 
					    eq(addr, meths.get_vvar('servername'))
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ local neq = global_helpers.neq
 | 
				
			|||||||
local eq = global_helpers.eq
 | 
					local eq = global_helpers.eq
 | 
				
			||||||
local ok = global_helpers.ok
 | 
					local ok = global_helpers.ok
 | 
				
			||||||
local map = global_helpers.map
 | 
					local map = global_helpers.map
 | 
				
			||||||
 | 
					local matches = global_helpers.matches
 | 
				
			||||||
local filter = global_helpers.filter
 | 
					local filter = global_helpers.filter
 | 
				
			||||||
local dedent = global_helpers.dedent
 | 
					local dedent = global_helpers.dedent
 | 
				
			||||||
local table_flatten = global_helpers.table_flatten
 | 
					local table_flatten = global_helpers.table_flatten
 | 
				
			||||||
@@ -747,6 +748,7 @@ local module = {
 | 
				
			|||||||
  insert = insert,
 | 
					  insert = insert,
 | 
				
			||||||
  iswin = iswin,
 | 
					  iswin = iswin,
 | 
				
			||||||
  map = map,
 | 
					  map = map,
 | 
				
			||||||
 | 
					  matches = matches,
 | 
				
			||||||
  merge_args = merge_args,
 | 
					  merge_args = merge_args,
 | 
				
			||||||
  meth_pcall = meth_pcall,
 | 
					  meth_pcall = meth_pcall,
 | 
				
			||||||
  meths = meths,
 | 
					  meths = meths,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,12 @@ end
 | 
				
			|||||||
local function ok(res)
 | 
					local function ok(res)
 | 
				
			||||||
  return assert.is_true(res)
 | 
					  return assert.is_true(res)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					local function matches(pat, actual)
 | 
				
			||||||
 | 
					  if nil ~= string.match(actual, pat) then
 | 
				
			||||||
 | 
					    return true
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  error(string.format('Pattern does not match.\nPattern:\n%s\nActual:\n%s', pat, actual))
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- initial_path:  directory to recurse into
 | 
					-- initial_path:  directory to recurse into
 | 
				
			||||||
-- re:            include pattern (string)
 | 
					-- re:            include pattern (string)
 | 
				
			||||||
@@ -572,6 +578,7 @@ return {
 | 
				
			|||||||
  hasenv = hasenv,
 | 
					  hasenv = hasenv,
 | 
				
			||||||
  intchar2lua = intchar2lua,
 | 
					  intchar2lua = intchar2lua,
 | 
				
			||||||
  map = map,
 | 
					  map = map,
 | 
				
			||||||
 | 
					  matches = matches,
 | 
				
			||||||
  mergedicts_copy = mergedicts_copy,
 | 
					  mergedicts_copy = mergedicts_copy,
 | 
				
			||||||
  neq = neq,
 | 
					  neq = neq,
 | 
				
			||||||
  ok = ok,
 | 
					  ok = ok,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user