patch 9.1.1651: Cannot use clientserver over socket
Problem: Cannot use clientserver over Unix domain socket Solution: Implement socketserver functionality (Foxe Chen). fixes: #3509 closes: #17839 Signed-off-by: Foxe Chen <chen.foxe@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
31170af24a
commit
96b2154b73
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
@ -85,6 +85,12 @@ jobs:
|
||||
- features: normal
|
||||
compiler: gcc
|
||||
extra: [vimtags]
|
||||
- features: huge
|
||||
compiler: gcc
|
||||
extra: [no_x11]
|
||||
- features: huge
|
||||
compiler: gcc
|
||||
extra: [socketserver]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository from github
|
||||
@ -220,7 +226,7 @@ jobs:
|
||||
tiny)
|
||||
echo "TEST=testtiny"
|
||||
if ${{ contains(matrix.extra, 'nogui') }}; then
|
||||
echo "CONFOPT=--disable-gui"
|
||||
CONFOPT="--disable-gui"
|
||||
fi
|
||||
;;
|
||||
normal)
|
||||
@ -232,10 +238,16 @@ jobs:
|
||||
PYTHON3_CONFOPT="--with-python3-stable-abi=3.8"
|
||||
fi
|
||||
# The ubuntu-24.04 CI runner does not provide a python2 package.
|
||||
echo "CONFOPT=--enable-perlinterp=${INTERFACE} --enable-pythoninterp=no --enable-python3interp=${INTERFACE} --enable-rubyinterp=${INTERFACE} --enable-luainterp=${INTERFACE} --enable-tclinterp=${INTERFACE} ${PYTHON3_CONFOPT}"
|
||||
CONFOPT="--enable-perlinterp=${INTERFACE} --enable-pythoninterp=no --enable-python3interp=${INTERFACE} --enable-rubyinterp=${INTERFACE} --enable-luainterp=${INTERFACE} --enable-tclinterp=${INTERFACE} ${PYTHON3_CONFOPT}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if ${{ contains(matrix.extra, 'no_x11') }}; then
|
||||
CONFOPT="${CONFOPT} --without-x --disable-gui"
|
||||
fi
|
||||
if ${{ contains(matrix.extra, 'socketserver') }}; then
|
||||
CONFOPT="${CONFOPT} --enable-socketserver"
|
||||
fi
|
||||
if ${{ matrix.coverage == true }}; then
|
||||
CFLAGS="${CFLAGS} --coverage -DUSE_GCOV_FLUSH"
|
||||
echo "LDFLAGS=--coverage"
|
||||
@ -259,6 +271,7 @@ jobs:
|
||||
echo "TEST=-C runtime/doc vimtags VIMEXE=../../${SRCDIR}/vim"
|
||||
fi
|
||||
echo "CFLAGS=${CFLAGS}"
|
||||
echo "CONFOPT=${CONFOPT}"
|
||||
# Disables GTK attempt to integrate with the accessibility service that does run in CI.
|
||||
echo "NO_AT_BRIDGE=1"
|
||||
) >> $GITHUB_ENV
|
||||
|
||||
@ -13046,6 +13046,7 @@ scrollbind Compiled with 'scrollbind' support. (always true)
|
||||
showcmd Compiled with 'showcmd' support.
|
||||
signs Compiled with |:sign| support.
|
||||
smartindent Compiled with 'smartindent' support. (always true)
|
||||
socketserver Compiled with socket server functionality. (Unix only)
|
||||
sodium Compiled with libsodium for better crypt support
|
||||
sound Compiled with sound support, e.g. `sound_playevent()`
|
||||
spell Compiled with spell checking support |spell|.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
*remote.txt* For Vim version 9.1. Last change: 2022 Feb 17
|
||||
*remote.txt* For Vim version 9.1. Last change: 2025 Aug 18
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -61,7 +61,10 @@ The following command line arguments are available:
|
||||
--servername {name} Become the server {name}. When used together
|
||||
with one of the --remote commands: connect to
|
||||
server {name} instead of the default (see
|
||||
below). The name used will be uppercase.
|
||||
below). The name used will be uppercase. If
|
||||
using the socketserver, you can specify a
|
||||
path, see |socketserver-name| for more
|
||||
details.
|
||||
*--remote-send*
|
||||
--remote-send {keys} Send {keys} to server and exit. The {keys}
|
||||
are not mapped. Special key names are
|
||||
@ -72,6 +75,12 @@ The following command line arguments are available:
|
||||
on stdout.
|
||||
*--serverlist*
|
||||
--serverlist Output a list of server names.
|
||||
*--clientserver*
|
||||
--clientserver {method} Use the specified method {method} as the
|
||||
backend for clientserver functionality. Can
|
||||
either be "socket" or "x11".
|
||||
{only available when Vim is compiled with both
|
||||
|+X11| and |+socketserver| features}
|
||||
|
||||
|
||||
Examples ~
|
||||
@ -105,7 +114,8 @@ specified name is not available, a postfix is applied until a free name is
|
||||
encountered, i.e. "gvim1" for the second invocation of gvim on a particular
|
||||
X-server. The resulting name is available in the servername builtin variable
|
||||
|v:servername|. The case of the server name is ignored, thus "gvim" and
|
||||
"GVIM" are considered equal.
|
||||
"GVIM" are considered equal. Note if a socket server is being used, there are
|
||||
some differences, see |socketserver-differences|.
|
||||
|
||||
When Vim is invoked with --remote, --remote-wait or --remote-send it will try
|
||||
to locate the server name determined by the invocation name and --servername
|
||||
@ -119,7 +129,8 @@ itself. This way it is not necessary to know whether gvim is already started
|
||||
when sending command to it.
|
||||
|
||||
The --serverlist argument will cause Vim to print a list of registered command
|
||||
servers on the standard output (stdout) and exit.
|
||||
servers on the standard output (stdout) and exit. If a socket server is being
|
||||
used, there are caveats, see |socketserver-differences|.
|
||||
*{server}*
|
||||
The {server} argument is used by several functions. When this is an empty
|
||||
string then on Unix the default server name is used, which is "GVIM". On
|
||||
@ -206,4 +217,64 @@ When using gvim, the --remote-wait only works properly this way: >
|
||||
|
||||
start /w gvim --remote-wait file.txt
|
||||
<
|
||||
==============================================================================
|
||||
3. Socket server specific items *socketserver-clientserver*
|
||||
*E1563* *E1564* *E1565* *E1566* *E1567*
|
||||
|
||||
The communication between client and server is done using Unix domain sockets.
|
||||
These sockets are either placed in these directories in the following order of
|
||||
availability:
|
||||
1. "$XDG_RUTIME_DIR/vim" if $XDG_RUNTIME_DIR is set in the environment.
|
||||
2. "$TMPDIR/vim-[uid]", where "[uid]" is the uid of the user. This
|
||||
directory will have the access permissions set to 700 so only the user
|
||||
can read or write from/to it. If $TMPDIR is not set, "/tmp" is used.
|
||||
|
||||
*socketserver-name*
|
||||
When specifying the server id/name, it can be taken as a generic name or an
|
||||
absolute or relative path. If the server id starts with either a "/"
|
||||
(absolute) or "./" | "../" (relative), then it is taken as path to the socket.
|
||||
Otherwise the server id will be the filename of the socket which will be
|
||||
placed in the above common directories. Note that a server id/name can only
|
||||
contain slashes "/" if it is taken as a path, so names such as "abc/dir" will
|
||||
be invalid.
|
||||
|
||||
Socket server functionality is available in both GTK GUI and terminal versions of
|
||||
Vim. Unless Vim is compiled with |+autoservername| feature, the socket server
|
||||
will have to started explicitly, just like X11, even in the GUI.
|
||||
|
||||
If Vim crashes or does not exit cleanly, the socket server will not remove the
|
||||
socket file and it will be left around. This is generally not a problem,
|
||||
because if a socket name is taken, Vim checks if the socket in its place is
|
||||
dead (not attached to any process), and can replace it instead of finding a
|
||||
new name.
|
||||
|
||||
To send commands to a Vim socket server from another application, read the
|
||||
source file src/os_unix.c, there is detailed description of the protocol used.
|
||||
|
||||
*socketserver-differences*
|
||||
Most of the functionality is the same as X11, however unlike X11, where the
|
||||
client does not need to be a server in order to communicate with another
|
||||
server, the socket server requires the server to be running even as a client.
|
||||
The exception is |serverlist()| or the |--serverlist| argument, which does not
|
||||
require the server to be running.
|
||||
|
||||
Additionally, the server id or client id will not be a number like X11 or
|
||||
MS-Windows (shown in hex representation), instead it is the absolute path to
|
||||
the socket. This can be seen via the |v:servername| variable.
|
||||
|
||||
The |--serverlist| argument will act just like X11, however it only checks the
|
||||
given common directories above. If a custom path is used for a socket, it
|
||||
will not be detected, such as a path either not in $XDG_RUNTIME_DIR or
|
||||
<$TMPDIR or /tmp>/vim of the |--serverlist| Vim process.
|
||||
|
||||
If you have both |+socketserver| and |+X11| compiled, you will need to add
|
||||
|--clientserver| set to "socket" in combination with |--serverlist| to list
|
||||
the available servers. You cannot list both types of backends in one command.
|
||||
|
||||
*socketserver-x11*
|
||||
If Vim is compiled with both |+X11| and |+socketserver|, then deciding which
|
||||
backend to use is done at startup time, via the |--clientserver| argument. By
|
||||
default if it is not specified, then X11 will be used. A Vim instance using a
|
||||
socket server cannot communicate with one using X11.
|
||||
|
||||
vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
|
||||
|
||||
@ -1497,6 +1497,7 @@ $quote eval.txt /*$quote*
|
||||
+scrollbind various.txt /*+scrollbind*
|
||||
+signs various.txt /*+signs*
|
||||
+smartindent various.txt /*+smartindent*
|
||||
+socketserver various.txt /*+socketserver*
|
||||
+sodium various.txt /*+sodium*
|
||||
+sound various.txt /*+sound*
|
||||
+spell various.txt /*+spell*
|
||||
@ -1557,6 +1558,7 @@ $quote eval.txt /*$quote*
|
||||
-- starting.txt /*--*
|
||||
--- starting.txt /*---*
|
||||
--clean starting.txt /*--clean*
|
||||
--clientserver remote.txt /*--clientserver*
|
||||
--cmd starting.txt /*--cmd*
|
||||
--echo-wid starting.txt /*--echo-wid*
|
||||
--gui-dialog-file starting.txt /*--gui-dialog-file*
|
||||
@ -4697,6 +4699,11 @@ E156 sign.txt /*E156*
|
||||
E1560 vim9.txt /*E1560*
|
||||
E1561 vim9.txt /*E1561*
|
||||
E1562 options.txt /*E1562*
|
||||
E1563 remote.txt /*E1563*
|
||||
E1564 remote.txt /*E1564*
|
||||
E1565 remote.txt /*E1565*
|
||||
E1566 remote.txt /*E1566*
|
||||
E1567 remote.txt /*E1567*
|
||||
E157 sign.txt /*E157*
|
||||
E158 sign.txt /*E158*
|
||||
E159 sign.txt /*E159*
|
||||
@ -10225,6 +10232,10 @@ slow-fast-terminal term.txt /*slow-fast-terminal*
|
||||
slow-start starting.txt /*slow-start*
|
||||
slow-terminal term.txt /*slow-terminal*
|
||||
socket-interface channel.txt /*socket-interface*
|
||||
socketserver-clientserver remote.txt /*socketserver-clientserver*
|
||||
socketserver-differences remote.txt /*socketserver-differences*
|
||||
socketserver-name remote.txt /*socketserver-name*
|
||||
socketserver-x11 remote.txt /*socketserver-x11*
|
||||
sort() builtin.txt /*sort()*
|
||||
sorting change.txt /*sorting*
|
||||
sound-functions usr_41.txt /*sound-functions*
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
*various.txt* For Vim version 9.1. Last change: 2025 Aug 06
|
||||
*various.txt* For Vim version 9.1. Last change: 2025 Aug 18
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -487,6 +487,8 @@ m *+ruby/dyn* Ruby interface |ruby-dynamic| |/dyn|
|
||||
T *+scrollbind* 'scrollbind'
|
||||
N *+signs* |:sign|
|
||||
T *+smartindent* 'smartindent'
|
||||
N *+socketserver* Unix only: socket server backend for clientserver
|
||||
functionality
|
||||
H *+sodium* compiled with libsodium for better encryption support
|
||||
H *+sound* |sound_playevent()|, |sound_playfile()| functions, etc.
|
||||
N *+spell* spell checking support, see |spell|
|
||||
|
||||
@ -41745,6 +41745,10 @@ Others: ~
|
||||
Unicode 16.
|
||||
- Two additional digraphs have been added: LEFT ANGLE BRACKET "<[" and RIGHT
|
||||
ANGLE BRACKET "]>".
|
||||
- Support for Unix domain sockets have been added for the clientserver
|
||||
feature, see |socketserver-clientserver|.
|
||||
|
||||
Platform specific ~
|
||||
- MS-Winodws: Paths like "\Windows" and "/Windows" are now considered to be
|
||||
absolute paths (to the current drive) and no longer relative.
|
||||
|
||||
@ -41849,6 +41853,7 @@ Options: ~
|
||||
|
||||
Vim Arguments: ~
|
||||
|-Y| Do not connect to the Wayland compositor.
|
||||
|--clientserver| Specify backend for clientserver functionality.
|
||||
|
||||
|
||||
==============================================================================
|
||||
|
||||
@ -499,7 +499,14 @@ List the names of all Vim servers that can be found.
|
||||
.TP
|
||||
\-\-servername {name}
|
||||
Use {name} as the server name. Used for the current Vim, unless used with a
|
||||
\-\-remote argument, then it's the name of the server to connect to.
|
||||
\-\-remote argument, then it's the name of the server to connect to. If the
|
||||
socketserver backend is being used, if the name starts with "/", "./", or "../",
|
||||
it is taken as either an absolute, relative or relative path to the socket.
|
||||
.TP
|
||||
\-\-clientserver {backend}
|
||||
Use {backend} as the backend for clientserver functionality, either "socket" or
|
||||
"x11" respectively. Only available when compiled with both socketserver and X11
|
||||
features present
|
||||
.TP
|
||||
\-\-socketid {id}
|
||||
GTK GUI only: Use the GtkPlug mechanism to run gVim in another window.
|
||||
|
||||
@ -378,7 +378,16 @@ OPTIONS
|
||||
--servername {name}
|
||||
Use {name} as the server name. Used for the current Vim,
|
||||
unless used with a --remote argument, then it's the name of
|
||||
the server to connect to.
|
||||
the server to connect to. If the socketserver backend is
|
||||
being used, if the name starts with "/", "./", or "../", it
|
||||
is taken as either an absolute, relative or relative path
|
||||
to the socket.
|
||||
|
||||
--clientserver {backend}
|
||||
Use {backend} as the backend for clientserver functional‐
|
||||
ity, either "socket" or "x11" respectively. Only available
|
||||
when compiled with both socketserver and X11 features
|
||||
present
|
||||
|
||||
--socketid {id}
|
||||
GTK GUI only: Use the GtkPlug mechanism to run gVim in an‐
|
||||
|
||||
@ -16,9 +16,10 @@ function SetupRemoteReplies()
|
||||
let max = argc()
|
||||
|
||||
let id = expand("<client>")
|
||||
if id == 0
|
||||
if (type(id) == v:t_number && id == 0) || (type(id) == v:t_string && id == '')
|
||||
return
|
||||
endif
|
||||
|
||||
while cnt < max
|
||||
" Handle same file from more clients and file being more than once
|
||||
" on the command line by encoding this stuff in the group name
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
" Language: Vim script
|
||||
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
|
||||
" Doug Kearns <dougkearns@gmail.com>
|
||||
" Last Change: 2025 Aug 16
|
||||
" Last Change: 2025 Aug 18
|
||||
" Former Maintainer: Charles E. Campbell
|
||||
|
||||
" DO NOT CHANGE DIRECTLY.
|
||||
|
||||
36
src/auto/configure
vendored
36
src/auto/configure
vendored
@ -854,6 +854,7 @@ enable_netbeans
|
||||
enable_channel
|
||||
enable_terminal
|
||||
enable_autoservername
|
||||
enable_socketserver
|
||||
enable_multibyte
|
||||
enable_rightleft
|
||||
enable_arabic
|
||||
@ -1534,6 +1535,7 @@ Optional Features:
|
||||
--disable-channel Disable process communication support.
|
||||
--enable-terminal Enable terminal emulation support.
|
||||
--enable-autoservername Automatically define servername at vim startup.
|
||||
--enable-socketserver Use sockets for clientserver communication.
|
||||
--enable-multibyte Include multibyte editing support.
|
||||
--disable-rightleft Do not include Right-to-Left language support.
|
||||
--disable-arabic Do not include Arabic language support.
|
||||
@ -9084,6 +9086,40 @@ if test "$enable_autoservername" = "yes"; then
|
||||
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --enable-socketserver argument" >&5
|
||||
printf %s "checking --enable-socketserver argument... " >&6; }
|
||||
# Check whether --enable-socketserver was given.
|
||||
if test ${enable_socketserver+y}
|
||||
then :
|
||||
enableval=$enable_socketserver; enable_socketserver=$enableval
|
||||
else case e in #(
|
||||
e) if test "x$features" = xtiny
|
||||
then :
|
||||
enable_socketserver=no_auto
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cannot use socketserver with tiny features" >&5
|
||||
printf "%s\n" "cannot use socketserver with tiny features" >&6; }
|
||||
else case e in #(
|
||||
e) enable_socketserver=auto ;;
|
||||
esac
|
||||
fi ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if test "$enable_socketserver" = "yes"; then
|
||||
printf "%s\n" "#define WANT_SOCKETSERVER 1" >>confdefs.h
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
elif test "$enable_socketserver" = "auto"; then
|
||||
printf "%s\n" "#define MAYBE_SOCKETSERVER 1" >>confdefs.h
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: auto" >&5
|
||||
printf "%s\n" "auto" >&6; }
|
||||
elif test "$enable_socketserver" = "no"; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --enable-multibyte argument" >&5
|
||||
printf %s "checking --enable-multibyte argument... " >&6; }
|
||||
# Check whether --enable-multibyte was given.
|
||||
|
||||
@ -15,6 +15,11 @@
|
||||
|
||||
#if defined(FEAT_CLIENTSERVER) || defined(PROTO)
|
||||
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
# include <sys/socket.h>
|
||||
# include "sys/un.h"
|
||||
#endif
|
||||
|
||||
static void cmdsrv_main(int *argc, char **argv, char_u *serverName_arg, char_u **serverStr);
|
||||
static char_u *serverMakeName(char_u *arg, char *cmd);
|
||||
|
||||
@ -191,6 +196,8 @@ static char_u *build_drop_cmd(int filec, char **filev, int tabs, int sendReply);
|
||||
void
|
||||
exec_on_server(mparm_T *parmp)
|
||||
{
|
||||
int made_name = FALSE;
|
||||
|
||||
if (parmp->serverName_arg != NULL && *parmp->serverName_arg == NUL)
|
||||
return;
|
||||
|
||||
@ -199,6 +206,23 @@ exec_on_server(mparm_T *parmp)
|
||||
serverInitMessaging();
|
||||
# endif
|
||||
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
// If servername is specified and we are using sockets, always init the
|
||||
// sockt server. We may need to receive replies back to us. If --serverlist
|
||||
// is passed, the socket server will be uninitialized before listing
|
||||
// sockets then initialized after. This is so we don't add our own socket
|
||||
// in the list. This does not happen in serverlist().
|
||||
if ((parmp->serverArg || parmp->serverName_arg != NULL) &&
|
||||
clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
{
|
||||
parmp->servername = serverMakeName(parmp->serverName_arg,
|
||||
parmp->argv[0]);
|
||||
if (socket_server_init(parmp->servername) == OK)
|
||||
TIME_MSG("initialize socket server");
|
||||
made_name = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When a command server argument was found, execute it. This may
|
||||
* exit Vim when it was successful. Otherwise it's executed further
|
||||
@ -214,8 +238,9 @@ exec_on_server(mparm_T *parmp)
|
||||
// If we're still running, get the name to register ourselves.
|
||||
// On Win32 can register right now, for X11 need to setup the
|
||||
// clipboard first, it's further down.
|
||||
parmp->servername = serverMakeName(parmp->serverName_arg,
|
||||
parmp->argv[0]);
|
||||
if (!made_name && parmp->servername == NULL)
|
||||
parmp->servername = serverMakeName(parmp->serverName_arg,
|
||||
parmp->argv[0]);
|
||||
# ifdef MSWIN
|
||||
if (parmp->servername != NULL)
|
||||
{
|
||||
@ -224,14 +249,13 @@ exec_on_server(mparm_T *parmp)
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for running as a Vim server.
|
||||
*/
|
||||
void
|
||||
prepare_server(mparm_T *parmp)
|
||||
{
|
||||
# if defined(FEAT_X11)
|
||||
# if defined(FEAT_X11) || defined(FEAT_SOCKETSERVER)
|
||||
/*
|
||||
* Register for remote command execution with :serversend and --remote
|
||||
* unless there was a -X or a --servername '' on the command line.
|
||||
@ -239,7 +263,13 @@ prepare_server(mparm_T *parmp)
|
||||
* or when compiling with autoservername.
|
||||
* When running as root --servername is also required.
|
||||
*/
|
||||
if (X_DISPLAY != NULL && parmp->servername != NULL && (
|
||||
|
||||
if (
|
||||
# ifdef FEAT_X11
|
||||
X_DISPLAY != NULL &&
|
||||
# endif
|
||||
|
||||
parmp->servername != NULL && (
|
||||
# if defined(FEAT_AUTOSERVERNAME) || defined(FEAT_GUI)
|
||||
(
|
||||
# if defined(FEAT_AUTOSERVERNAME)
|
||||
@ -254,12 +284,26 @@ prepare_server(mparm_T *parmp)
|
||||
# endif
|
||||
parmp->serverName_arg != NULL))
|
||||
{
|
||||
(void)serverRegisterName(X_DISPLAY, parmp->servername);
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
{
|
||||
if (socket_server_init(parmp->servername) == OK)
|
||||
TIME_MSG("initialize socket server");
|
||||
}
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
{
|
||||
(void)serverRegisterName(X_DISPLAY, parmp->servername);
|
||||
TIME_MSG("register x11 server name");
|
||||
}
|
||||
# endif
|
||||
vim_free(parmp->servername);
|
||||
TIME_MSG("register server name");
|
||||
}
|
||||
#ifdef FEAT_X11
|
||||
else
|
||||
serverDelayedStartName = parmp->servername;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/*
|
||||
@ -299,9 +343,12 @@ cmdsrv_main(
|
||||
#define ARGTYPE_SEND 3
|
||||
int silent = FALSE;
|
||||
int tabs = FALSE;
|
||||
# ifndef FEAT_X11
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
char_u *receiver;
|
||||
#endif
|
||||
# ifdef MSWIN
|
||||
HWND srv;
|
||||
# else
|
||||
# elif defined(FEAT_X11)
|
||||
Window srv;
|
||||
|
||||
setup_term_clip();
|
||||
@ -384,16 +431,27 @@ cmdsrv_main(
|
||||
}
|
||||
Argc = i;
|
||||
}
|
||||
# ifdef FEAT_X11
|
||||
if (xterm_dpy == NULL)
|
||||
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
ret = socket_server_send(
|
||||
sname, *serverStr, NULL, &receiver,
|
||||
0, -1, silent);
|
||||
#endif
|
||||
#ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
{
|
||||
mch_errmsg(_("No display"));
|
||||
ret = -1;
|
||||
if (xterm_dpy == NULL)
|
||||
{
|
||||
mch_errmsg(_("No display"));
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
ret = serverSendToVim(xterm_dpy, sname, *serverStr,
|
||||
NULL, &srv, 0, 0, 0, silent);
|
||||
}
|
||||
else
|
||||
ret = serverSendToVim(xterm_dpy, sname, *serverStr,
|
||||
NULL, &srv, 0, 0, 0, silent);
|
||||
# else
|
||||
#endif
|
||||
#ifdef MSWIN
|
||||
// Win32 always works?
|
||||
ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, 0, silent);
|
||||
# endif
|
||||
@ -452,14 +510,24 @@ cmdsrv_main(
|
||||
vim_memset(done, 0, numFiles);
|
||||
while (memchr(done, 0, numFiles) != NULL)
|
||||
{
|
||||
char_u *p;
|
||||
char_u *p = NULL;
|
||||
int j;
|
||||
# ifdef MSWIN
|
||||
p = serverGetReply(srv, NULL, TRUE, TRUE, 0);
|
||||
if (p == NULL)
|
||||
break;
|
||||
# else
|
||||
if (serverReadReply(xterm_dpy, srv, &p, TRUE, -1) < 0)
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET
|
||||
&& socket_server_read_reply(receiver, &p, -1) == FAIL)
|
||||
break;
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11
|
||||
&& serverReadReply(xterm_dpy, srv, &p, TRUE, -1) < 0)
|
||||
break;
|
||||
# endif
|
||||
if (p == NULL)
|
||||
break;
|
||||
# endif
|
||||
j = atoi((char *)p);
|
||||
@ -490,12 +558,34 @@ cmdsrv_main(
|
||||
if (serverSendToVim(sname, (char_u *)argv[i + 1],
|
||||
&res, NULL, 1, 0, FALSE) < 0)
|
||||
# else
|
||||
if (xterm_dpy == NULL)
|
||||
mch_errmsg(_("No display: Send expression failed.\n"));
|
||||
else if (serverSendToVim(xterm_dpy, sname, (char_u *)argv[i + 1],
|
||||
&res, NULL, 1, 0, 1, FALSE) < 0)
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
{
|
||||
if (!socket_server_valid())
|
||||
mch_errmsg(_("Socket server not online:"
|
||||
"Send expression failed"));
|
||||
else if (socket_server_send(sname, (char_u *)argv[i + 1],
|
||||
&res, NULL, 1, 0, FALSE) < 0)
|
||||
goto expr_fail;
|
||||
}
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
{
|
||||
if (xterm_dpy == NULL)
|
||||
mch_errmsg(_("No display: Send expression failed.\n"));
|
||||
else if (serverSendToVim(xterm_dpy, sname,
|
||||
(char_u *)argv[i + 1], &res,
|
||||
NULL, 1, 0, 1, FALSE) < 0)
|
||||
goto expr_fail;
|
||||
}
|
||||
# endif
|
||||
if (FALSE)
|
||||
# endif
|
||||
{
|
||||
# if !defined(MSWIN)
|
||||
expr_fail:
|
||||
# endif
|
||||
if (res != NULL && *res != NUL)
|
||||
{
|
||||
// Output error from remote
|
||||
@ -511,8 +601,25 @@ cmdsrv_main(
|
||||
// Win32 always works?
|
||||
res = serverGetVimNames();
|
||||
# else
|
||||
if (xterm_dpy != NULL)
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
{
|
||||
int was_init = socket_server_valid();
|
||||
|
||||
// Don't want to add ourselves to the list. So shutdown the
|
||||
// server before listing then startup back again.
|
||||
socket_server_uninit();
|
||||
res = socket_server_list_sockets();
|
||||
|
||||
if (was_init)
|
||||
socket_server_init(NULL);
|
||||
}
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11 &&
|
||||
xterm_dpy != NULL)
|
||||
res = serverGetVimNames(xterm_dpy);
|
||||
# endif
|
||||
# endif
|
||||
if (did_emsg)
|
||||
mch_errmsg("\n");
|
||||
@ -541,6 +648,9 @@ cmdsrv_main(
|
||||
|
||||
if (didone)
|
||||
{
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
socket_server_uninit();
|
||||
#endif
|
||||
display_errors(); // display any collected messages
|
||||
exit(exiterr); // Mission accomplished - get out
|
||||
}
|
||||
@ -694,7 +804,24 @@ serverMakeName(char_u *arg, char *cmd)
|
||||
char_u *p;
|
||||
|
||||
if (arg != NULL && *arg != NUL)
|
||||
{
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
// If we are using a socket server, we want to preserve the original
|
||||
// name if it is a path, else uppercase it if its just a generic name.
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
{
|
||||
if (arg[0] == '/' || STRNCMP(arg, "./", 2) == 0 ||
|
||||
STRNCMP(arg, "../", 3) == 0)
|
||||
p = vim_strsave(arg);
|
||||
else
|
||||
p = vim_strsave_up(arg);
|
||||
}
|
||||
else
|
||||
p = vim_strsave_up(arg);
|
||||
#else
|
||||
p = vim_strsave_up(arg);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
p = vim_strsave_up(gettail((char_u *)cmd));
|
||||
@ -747,7 +874,12 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
|
||||
# ifdef MSWIN
|
||||
HWND w;
|
||||
# else
|
||||
#ifdef FEAT_X11
|
||||
Window w;
|
||||
#endif
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
char_u *client = NULL;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
if (check_restricted() || check_secure())
|
||||
@ -768,14 +900,33 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
|
||||
# ifdef MSWIN
|
||||
if (serverSendToVim(server_name, keys, &r, &w, expr, timeout, TRUE) < 0)
|
||||
# else
|
||||
if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, timeout,
|
||||
0, TRUE) < 0)
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
if (socket_server_send(server_name, keys, &r, &client, expr,
|
||||
timeout * 1000, TRUE) < 0)
|
||||
goto stuff;
|
||||
#endif
|
||||
#ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, timeout,
|
||||
0, TRUE) < 0)
|
||||
goto stuff;
|
||||
#endif
|
||||
# endif
|
||||
#if !defined(MSWIN)
|
||||
if (FALSE)
|
||||
{
|
||||
stuff:
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
if (r != NULL)
|
||||
{
|
||||
emsg((char *)r); // sending worked but evaluation failed
|
||||
vim_free(r);
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
vim_free(client);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
semsg(_(e_unable_to_send_to_str), server_name);
|
||||
@ -787,19 +938,39 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
dictitem_T v;
|
||||
#if defined(FEAT_SOCKETSERVER)
|
||||
struct sockaddr_un addr;
|
||||
char_u str[sizeof(addr.sun_path)];
|
||||
#else
|
||||
char_u str[30];
|
||||
#endif
|
||||
char_u *idvar;
|
||||
|
||||
idvar = tv_get_string_chk(&argvars[2]);
|
||||
if (idvar != NULL && *idvar != NUL)
|
||||
{
|
||||
#ifdef MSWIN
|
||||
sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
|
||||
#else
|
||||
#ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
|
||||
#endif
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
vim_snprintf((char *)str, sizeof(addr.sun_path),
|
||||
"%s", client);
|
||||
#endif
|
||||
#endif
|
||||
v.di_tv.v_type = VAR_STRING;
|
||||
v.di_tv.vval.v_string = vim_strsave(str);
|
||||
set_var(idvar, &v.di_tv, FALSE);
|
||||
vim_free(v.di_tv.vval.v_string);
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
vim_free(client);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -890,11 +1061,20 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
rettv->vval.v_number = (s != NULL);
|
||||
}
|
||||
# else
|
||||
if (check_connection() == FAIL)
|
||||
return;
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
rettv->vval.v_number = socket_server_peek_reply(serverid, &s);
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
{
|
||||
if (check_connection() == FAIL)
|
||||
return;
|
||||
|
||||
rettv->vval.v_number = serverPeekReply(X_DISPLAY,
|
||||
serverStrToWin(serverid), &s);
|
||||
rettv->vval.v_number = serverPeekReply(X_DISPLAY,
|
||||
serverStrToWin(serverid), &s);
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0)
|
||||
@ -943,12 +1123,21 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
if (n != 0)
|
||||
r = serverGetReply((HWND)n, FALSE, TRUE, TRUE, timeout);
|
||||
if (r == NULL)
|
||||
# else
|
||||
if (check_connection() == FAIL
|
||||
|| serverReadReply(X_DISPLAY, serverStrToWin(serverid),
|
||||
&r, FALSE, timeout) < 0)
|
||||
# endif
|
||||
emsg(_(e_unable_to_read_server_reply));
|
||||
# else
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET &&
|
||||
socket_server_read_reply(serverid, &r, timeout * 1000) == FAIL)
|
||||
emsg(_(e_unable_to_read_server_reply));
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11 &&
|
||||
(check_connection() == FAIL
|
||||
|| serverReadReply(X_DISPLAY, serverStrToWin(serverid),
|
||||
&r, FALSE, timeout) < 0))
|
||||
emsg(_(e_unable_to_read_server_reply));
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
rettv->v_type = VAR_STRING;
|
||||
@ -992,11 +1181,18 @@ f_remote_startserver(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||
}
|
||||
|
||||
char_u *server = tv_get_string_chk(&argvars[0]);
|
||||
# ifdef FEAT_X11
|
||||
if (check_connection() == OK)
|
||||
serverRegisterName(X_DISPLAY, server);
|
||||
# else
|
||||
# ifdef MSWIN
|
||||
serverSetName(server);
|
||||
# else
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
socket_server_init(server);
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11 &&
|
||||
check_connection() == OK)
|
||||
serverRegisterName(X_DISPLAY, server);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#else
|
||||
@ -1026,13 +1222,30 @@ f_server2client(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
if (server == NULL || reply == NULL)
|
||||
return;
|
||||
|
||||
# ifdef FEAT_X11
|
||||
if (check_connection() == FAIL)
|
||||
return;
|
||||
# endif
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET &&
|
||||
socket_server_send_reply(server, reply) == FAIL)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11 &&
|
||||
check_connection() == FAIL)
|
||||
return;
|
||||
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11 &&
|
||||
serverSendReply(server, reply) < 0)
|
||||
#endif
|
||||
#ifdef MSWIN
|
||||
if (serverSendReply(server, reply) < 0)
|
||||
#endif
|
||||
#if defined(FEAT_SOCKETSERVER) && !defined(FEAT_X11) && !defined(MSWIN)
|
||||
if (FALSE)
|
||||
#endif
|
||||
{
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
fail:
|
||||
#endif
|
||||
emsg(_(e_unable_to_send_to_client));
|
||||
return;
|
||||
}
|
||||
@ -1051,9 +1264,18 @@ f_serverlist(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
# ifdef MSWIN
|
||||
r = serverGetVimNames();
|
||||
# else
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
r = socket_server_list_sockets();
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
{
|
||||
make_connection();
|
||||
if (X_DISPLAY != NULL)
|
||||
r = serverGetVimNames(X_DISPLAY);
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
rettv->v_type = VAR_STRING;
|
||||
|
||||
@ -406,6 +406,12 @@
|
||||
/* Define if you want to always define a server name at vim startup. */
|
||||
#undef FEAT_AUTOSERVERNAME
|
||||
|
||||
/* Define if you want to use sockets for clientserver communication. */
|
||||
#undef WANT_SOCKETSERVER
|
||||
|
||||
/* Define if you want to use sockets for clientserver communication if it makes sense. */
|
||||
#undef MAYBE_SOCKETSERVER
|
||||
|
||||
/* Define if you want to include fontset support. */
|
||||
#undef FEAT_XFONTSET
|
||||
|
||||
|
||||
@ -2340,6 +2340,24 @@ if test "$enable_autoservername" = "yes"; then
|
||||
AC_DEFINE(FEAT_AUTOSERVERNAME)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(--enable-socketserver argument)
|
||||
AC_ARG_ENABLE(socketserver,
|
||||
[ --enable-socketserver Use sockets for clientserver communication.],
|
||||
[enable_socketserver=$enableval],
|
||||
AS_IF([test "x$features" = xtiny],
|
||||
[enable_socketserver=no_auto
|
||||
AC_MSG_RESULT([cannot use socketserver with tiny features])],
|
||||
[enable_socketserver=auto]))
|
||||
if test "$enable_socketserver" = "yes"; then
|
||||
AC_DEFINE(WANT_SOCKETSERVER)
|
||||
AC_MSG_RESULT([yes])
|
||||
elif test "$enable_socketserver" = "auto"; then
|
||||
AC_DEFINE(MAYBE_SOCKETSERVER)
|
||||
AC_MSG_RESULT([auto])
|
||||
elif test "$enable_socketserver" = "no"; then
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(--enable-multibyte argument)
|
||||
AC_ARG_ENABLE(multibyte,
|
||||
[ --enable-multibyte Include multibyte editing support.], ,
|
||||
|
||||
12
src/errors.h
12
src/errors.h
@ -3782,3 +3782,15 @@ EXTERN char e_duplicate_type_var_name_str[]
|
||||
EXTERN char e_diff_anchors_with_hidden_windows[]
|
||||
INIT(= N_("E1562: Diff anchors cannot be used with hidden diff windows"));
|
||||
#endif
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
EXTERN char e_socket_path_too_big[]
|
||||
INIT(= N_("E1563: Socket path is too big"));
|
||||
EXTERN char e_socket_name_no_slashes[]
|
||||
INIT(= N_("E1564: Socket name cannot have slashes in it without being a path"));
|
||||
EXTERN char e_socket_server_not_online[]
|
||||
INIT(= N_("E1565: Socket server is not online, call remote_startserver() first"));
|
||||
EXTERN char e_socket_server_failed_connecting[]
|
||||
INIT(= N_("E1566: Failed connecting to socket %s: %s"));
|
||||
EXTERN char e_socket_server_unavailable[]
|
||||
INIT(= N_("E1567: Cannot start socket server, socket path is unavailable"));
|
||||
#endif
|
||||
|
||||
@ -6765,6 +6765,13 @@ f_has(typval_T *argvars, typval_T *rettv)
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
},
|
||||
{"socketserver",
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
},
|
||||
{"balloon_eval",
|
||||
|
||||
@ -10039,9 +10039,29 @@ eval_vars(
|
||||
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
case SPEC_CLIENT: // Source of last submitted input
|
||||
#ifdef MSWIN
|
||||
sprintf((char *)strbuf, PRINTF_HEX_LONG_U,
|
||||
(long_u)clientWindow);
|
||||
result = strbuf;
|
||||
#else
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_SOCKET)
|
||||
{
|
||||
if (client_socket == NULL)
|
||||
result = (char_u *)"";
|
||||
else
|
||||
result = client_socket;
|
||||
}
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11)
|
||||
{
|
||||
sprintf((char *)strbuf, PRINTF_HEX_LONG_U,
|
||||
(long_u)clientWindow);
|
||||
result = strbuf;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
@ -945,11 +945,20 @@
|
||||
# define FIND_REPLACE_DIALOG 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* +socketserver Use UNIX domain sockets for clientserver communication
|
||||
*/
|
||||
#if defined(UNIX) && (defined(WANT_SOCKETSERVER) || \
|
||||
(defined(MAYBE_SOCKETSERVER) && !defined(HAVE_X11)))
|
||||
#define FEAT_SOCKETSERVER
|
||||
#endif
|
||||
|
||||
/*
|
||||
* +clientserver Remote control via the remote_send() function
|
||||
* and the --remote argument
|
||||
*/
|
||||
#if (defined(MSWIN) || defined(FEAT_XCLIPBOARD)) && defined(FEAT_EVAL)
|
||||
#if (defined(MSWIN) || defined(FEAT_XCLIPBOARD) || defined(FEAT_SOCKETSERVER)) \
|
||||
&& defined(FEAT_EVAL)
|
||||
# define FEAT_CLIENTSERVER
|
||||
#endif
|
||||
|
||||
|
||||
@ -1868,7 +1868,7 @@ EXTERN Window commWindow INIT(= None);
|
||||
EXTERN Window clientWindow INIT(= None);
|
||||
EXTERN Atom commProperty INIT(= None);
|
||||
EXTERN char_u *serverDelayedStartName INIT(= NULL);
|
||||
# else
|
||||
# elif defined(MSWIN)
|
||||
# ifdef PROTO
|
||||
typedef int HWND;
|
||||
# endif
|
||||
@ -2090,3 +2090,35 @@ EXTERN char *wayland_display_name INIT(= NULL);
|
||||
EXTERN int wayland_display_fd;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_CLIENTSERVER) && !defined(MSWIN)
|
||||
|
||||
// Backend for clientserver functionality
|
||||
typedef enum {
|
||||
CLIENTSERVER_METHOD_NONE,
|
||||
CLIENTSERVER_METHOD_X11,
|
||||
CLIENTSERVER_METHOD_SOCKET
|
||||
} clientserver_method_T;
|
||||
|
||||
// Default to X11 if compiled with support for it, else use socket server.
|
||||
# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER)
|
||||
EXTERN clientserver_method_T clientserver_method
|
||||
# else
|
||||
// Since we aren't going to be changing clientserver_method, make it constant to
|
||||
// allow compiler optimizations.
|
||||
EXTERN const clientserver_method_T clientserver_method
|
||||
# endif
|
||||
# ifdef FEAT_X11
|
||||
INIT(= CLIENTSERVER_METHOD_X11);
|
||||
# elif defined(FEAT_SOCKETSERVER)
|
||||
INIT(= CLIENTSERVER_METHOD_SOCKET);
|
||||
# else
|
||||
INIT(= CLIENTSERVER_METHOD_NONE);
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
// Path to socket of last client that communicated with us
|
||||
EXTERN char_u *client_socket INIT(= NULL);
|
||||
#endif
|
||||
|
||||
@ -150,6 +150,12 @@ gui_start(char_u *arg UNUSED)
|
||||
// Reset clipmethod to CLIPMETHOD_NONE
|
||||
choose_clipmethod();
|
||||
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
// Install socket server listening socket if we are running it
|
||||
if (socket_server_valid())
|
||||
gui_gtk_init_socket_server();
|
||||
#endif
|
||||
|
||||
vim_free(old_term);
|
||||
|
||||
// If the GUI started successfully, trigger the GUIEnter event, otherwise
|
||||
|
||||
@ -99,6 +99,13 @@ extern void bonobo_dock_item_set_behavior(BonoboDockItem *dock_item, BonoboDockI
|
||||
# include <X11/Sunkeysym.h>
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
# include <glib-unix.h>
|
||||
|
||||
// Used to track the source for the listening socket
|
||||
static uint socket_server_source_id = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Easy-to-use macro for multihead support.
|
||||
*/
|
||||
@ -2688,6 +2695,53 @@ global_event_filter(GdkXEvent *xev,
|
||||
}
|
||||
#endif // !USE_GNOME_SESSION
|
||||
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
|
||||
/*
|
||||
* Callback for new events from the socket server listening socket
|
||||
*/
|
||||
static int
|
||||
socket_server_poll_in(int fd UNUSED, GIOCondition cond, void *user_data UNUSED)
|
||||
{
|
||||
if (cond & G_IO_IN)
|
||||
socket_server_accept_client();
|
||||
else if (cond & (G_IO_ERR | G_IO_HUP))
|
||||
{
|
||||
socket_server_uninit();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize socket server for use in the GUI (does not actually initialize the
|
||||
* socket server, only attaches a source).
|
||||
*/
|
||||
void
|
||||
gui_gtk_init_socket_server(void)
|
||||
{
|
||||
if (socket_server_source_id > 0)
|
||||
return;
|
||||
// Register source for file descriptor to global default context
|
||||
socket_server_source_id = g_unix_fd_add(socket_server_get_fd(),
|
||||
G_IO_IN | G_IO_ERR | G_IO_HUP, socket_server_poll_in, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the source for the socket server listening socket.
|
||||
*/
|
||||
void
|
||||
gui_gtk_uninit_socket_server(void)
|
||||
{
|
||||
if (socket_server_source_id > 0)
|
||||
{
|
||||
g_source_remove(socket_server_source_id);
|
||||
socket_server_source_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the window icon & xcmdsrv comm after the main window has been realized.
|
||||
@ -2754,7 +2808,7 @@ mainwin_realize(GtkWidget *widget UNUSED, gpointer data UNUSED)
|
||||
setup_save_yourself();
|
||||
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
if (gui_mch_get_display())
|
||||
if (clientserver_method == CLIENTSERVER_METHOD_X11 && gui_mch_get_display())
|
||||
{
|
||||
if (serverName == NULL && serverDelayedStartName != NULL)
|
||||
{
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include "vim.h"
|
||||
#include "version.h"
|
||||
|
||||
#if defined(FEAT_CLIENTSERVER) || defined(PROTO)
|
||||
#if (defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)) || defined(PROTO)
|
||||
|
||||
# ifdef FEAT_X11
|
||||
# include <X11/Intrinsic.h>
|
||||
|
||||
28
src/main.c
28
src/main.c
@ -1855,7 +1855,8 @@ getout(int exitval)
|
||||
* Get the name of the display, before gui_prepare() removes it from
|
||||
* argv[]. Used for the xterm-clipboard display.
|
||||
*
|
||||
* Also find the --server... arguments and --socketid and --windowid
|
||||
* Also find the --server, --clientserver... arguments and --socketid and
|
||||
* --windowid
|
||||
*/
|
||||
static void
|
||||
early_arg_scan(mparm_T *parmp UNUSED)
|
||||
@ -1900,6 +1901,22 @@ early_arg_scan(mparm_T *parmp UNUSED)
|
||||
gui.dofork = FALSE;
|
||||
# endif
|
||||
}
|
||||
# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER)
|
||||
else if (STRNICMP(argv[i], "--clientserver", 14) == 0)
|
||||
{
|
||||
char_u *arg;
|
||||
if (i == argc - 1)
|
||||
mainerr_arg_missing((char_u *)argv[i]);
|
||||
arg = (char_u *)argv[++i];
|
||||
|
||||
if (STRICMP(arg, "socket") == 0)
|
||||
clientserver_method = CLIENTSERVER_METHOD_SOCKET;
|
||||
else if (STRICMP(arg, "x11") == 0)
|
||||
clientserver_method = CLIENTSERVER_METHOD_X11;
|
||||
else
|
||||
mainerr(ME_UNKNOWN_OPTION, arg);
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN)
|
||||
@ -2220,7 +2237,11 @@ command_line_scan(mparm_T *parmp)
|
||||
else if (STRNICMP(argv[0] + argv_idx, "serverlist", 10) == 0)
|
||||
; // already processed -- no arg
|
||||
else if (STRNICMP(argv[0] + argv_idx, "servername", 10) == 0
|
||||
|| STRNICMP(argv[0] + argv_idx, "serversend", 10) == 0)
|
||||
|| STRNICMP(argv[0] + argv_idx, "serversend", 10) == 0
|
||||
# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER)
|
||||
|| STRNICMP(argv[0] + argv_idx, "clientserver", 12) == 0
|
||||
# endif
|
||||
)
|
||||
{
|
||||
// already processed -- snatch the following arg
|
||||
if (argc > 1)
|
||||
@ -3712,6 +3733,9 @@ usage(void)
|
||||
main_msg(_("-Y\t\t\tDo not connect to Wayland compositor"));
|
||||
#endif
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER)
|
||||
main_msg(_("--clientserver <socket|x11> Backend for clientserver communication"));
|
||||
# endif
|
||||
main_msg(_("--remote <files>\tEdit <files> in a Vim server if possible"));
|
||||
main_msg(_("--remote-silent <files> Same, don't complain if there is no server"));
|
||||
main_msg(_("--remote-wait <files> As --remote but wait for files to have been edited"));
|
||||
|
||||
1717
src/os_unix.c
1717
src/os_unix.c
File diff suppressed because it is too large
Load Diff
28
src/po/vim.pot
generated
28
src/po/vim.pot
generated
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Vim\n"
|
||||
"Report-Msgid-Bugs-To: vim-dev@vim.org\n"
|
||||
"POT-Creation-Date: 2025-08-16 17:57+0200\n"
|
||||
"POT-Creation-Date: 2025-08-18 21:30+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -254,6 +254,9 @@ msgstr ""
|
||||
msgid "%d of %d edited"
|
||||
msgstr ""
|
||||
|
||||
msgid "Socket server not online:Send expression failed"
|
||||
msgstr ""
|
||||
|
||||
msgid "No display: Send expression failed.\n"
|
||||
msgstr ""
|
||||
|
||||
@ -1711,6 +1714,9 @@ msgstr ""
|
||||
msgid "-Y\t\t\tDo not connect to Wayland compositor"
|
||||
msgstr ""
|
||||
|
||||
msgid "--clientserver <socket|x11> Backend for clientserver communication"
|
||||
msgstr ""
|
||||
|
||||
msgid "--remote <files>\tEdit <files> in a Vim server if possible"
|
||||
msgstr ""
|
||||
|
||||
@ -2507,6 +2513,10 @@ msgstr ""
|
||||
msgid "XSMP SmcOpenConnection failed: %s"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "Failed creating socket directory: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "At line"
|
||||
msgstr ""
|
||||
|
||||
@ -8806,6 +8816,22 @@ msgstr ""
|
||||
msgid "E1562: Diff anchors cannot be used with hidden diff windows"
|
||||
msgstr ""
|
||||
|
||||
msgid "E1563: Socket path is too big"
|
||||
msgstr ""
|
||||
|
||||
msgid "E1564: Socket name cannot have slashes in it without being a path"
|
||||
msgstr ""
|
||||
|
||||
msgid "E1565: Socket server is not online, call remote_startserver() first"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "E1566: Failed connecting to socket %s: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "E1567: Cannot start socket server, socket path is unavailable"
|
||||
msgstr ""
|
||||
|
||||
#. type of cmdline window or 0
|
||||
#. result of cmdline window or 0
|
||||
#. buffer of cmdline window or NULL
|
||||
|
||||
@ -8,6 +8,8 @@ void gui_mch_stop_blink(int may_call_gui_update_cursor);
|
||||
void gui_mch_start_blink(void);
|
||||
int gui_mch_early_init_check(int give_message);
|
||||
int gui_mch_init_check(void);
|
||||
void gui_gtk_init_socket_server(void);
|
||||
void gui_gtk_uninit_socket_server(void);
|
||||
void gui_mch_set_dark_theme(int dark);
|
||||
void gui_mch_show_tabline(int showit);
|
||||
int gui_mch_showing_tabline(void);
|
||||
|
||||
@ -68,6 +68,7 @@ char *did_set_shellslash(optset_T *args);
|
||||
char *did_set_shiftwidth_tabstop(optset_T *args);
|
||||
char *did_set_showtabline(optset_T *args);
|
||||
char *did_set_smoothscroll(optset_T *args);
|
||||
char *did_set_socktimeoutlen(optset_T *args);
|
||||
char *did_set_spell(optset_T *args);
|
||||
char *did_set_swapfile(optset_T *args);
|
||||
char *did_set_termguicolors(optset_T *args);
|
||||
|
||||
@ -34,6 +34,8 @@ int expand_set_casemap(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||
int expand_set_clipboard(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||
char *did_set_clipmethod(optset_T *args);
|
||||
int expand_set_clipmethod(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||
char *did_set_clientserver(optset_T *args UNUSED);
|
||||
int expand_set_clientserver(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||
char *did_set_chars_option(optset_T *args);
|
||||
int expand_set_chars_option(optexpand_T *args, int *numMatches, char_u ***matches);
|
||||
char *did_set_cinoptions(optset_T *args);
|
||||
|
||||
@ -94,4 +94,15 @@ void stop_timeout(void);
|
||||
volatile sig_atomic_t *start_timeout(long msec);
|
||||
void delete_timer(void);
|
||||
int mch_create_anon_file(void);
|
||||
int socket_server_init(char_u *sock_path);
|
||||
void socket_server_uninit(void);
|
||||
char_u *socket_server_list_sockets(void);
|
||||
void socket_server_accept_client(void);
|
||||
int socket_server_valid(void);
|
||||
int socket_server_send(char_u *sock_path, char_u *cmd, char_u **result, char_u **receiver, int is_expr, int timeout, int silent);
|
||||
int socket_server_read_reply(char_u *sender, char_u **str, int timeout);
|
||||
int socket_server_peek_reply(char_u *sender, char_u **str);
|
||||
int socket_server_send_reply(char_u *client, char_u *str);
|
||||
int socket_server_get_fd(void);
|
||||
int socket_server_waiting_accept(void);
|
||||
/* vim: set ft=c : */
|
||||
|
||||
@ -10,6 +10,12 @@ CheckFeature clientserver
|
||||
|
||||
source util/shared.vim
|
||||
|
||||
" Unlike X11, we need the socket server running if we want to send commands to
|
||||
" a server via sockets.
|
||||
if v:servername == ""
|
||||
call remote_startserver('VIMSOCKETSERVERTEST')
|
||||
endif
|
||||
|
||||
func Check_X11_Connection()
|
||||
if has('x11')
|
||||
CheckX11
|
||||
@ -184,10 +190,18 @@ func Test_client_server()
|
||||
call assert_fails('call remote_startserver("")', 'E1175:')
|
||||
call assert_fails('call remote_startserver([])', 'E1174:')
|
||||
call assert_fails("let x = remote_peek([])", 'E730:')
|
||||
call assert_fails("let x = remote_read('vim10')",
|
||||
\ has('unix') ? ['E573:.*vim10'] : 'E277:')
|
||||
call assert_fails("call server2client('abc', 'xyz')",
|
||||
\ has('unix') ? ['E573:.*abc'] : 'E258:')
|
||||
|
||||
" When using socket server, server id is not a number, but the path to the
|
||||
" socket.
|
||||
if has('socketserver') && !has('X11')
|
||||
call assert_fails("let x = remote_read('vim/10')", ['E573:.*vim/10'])
|
||||
call assert_fails("call server2client('a/b/c', 'xyz')", ['E573:.*a/b/c'])
|
||||
else
|
||||
call assert_fails("let x = remote_read('vim10')",
|
||||
\ has('unix') ? ['E573:.*vim10'] : 'E277:')
|
||||
call assert_fails("call server2client('abc', 'xyz')",
|
||||
\ has('unix') ? ['E573:.*abc'] : 'E258:')
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_client_server_stopinsert()
|
||||
@ -231,6 +245,121 @@ func Test_client_server_stopinsert()
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" Test if socket server and X11 backends can be chosen and work properly.
|
||||
func Test_client_server_x11_and_socket_server()
|
||||
CheckNotMSWindows
|
||||
CheckFeature socketserver
|
||||
CheckFeature x11
|
||||
|
||||
let g:test_is_flaky = 1
|
||||
let cmd = GetVimCommand()
|
||||
|
||||
if cmd == ''
|
||||
throw 'GetVimCommand() failed'
|
||||
endif
|
||||
call Check_X11_Connection()
|
||||
|
||||
let types = ['socket', 'x11']
|
||||
|
||||
for type in types
|
||||
let name = 'VIMTEST_' .. toupper(type)
|
||||
let actual_cmd = cmd .. ' --clientserver ' .. type
|
||||
let actual_cmd .= ' --servername ' .. name
|
||||
let job = job_start(actual_cmd, {'stoponexit': 'kill', 'out_io': 'null'})
|
||||
|
||||
call WaitForAssert({-> assert_equal("run", job_status(job))})
|
||||
call WaitForAssert({-> assert_match(name, system(cmd .. ' --clientserver ' .. type .. ' --serverlist'))})
|
||||
|
||||
call assert_match(name, system(actual_cmd .. ' --remote-expr "v:servername"'))
|
||||
|
||||
call system(actual_cmd .. " --remote-expr 'execute(\"qa!\")'")
|
||||
try
|
||||
call WaitForAssert({-> assert_equal("dead", job_status(job))})
|
||||
finally
|
||||
if job_status(job) != 'dead'
|
||||
call assert_report('Server did not exit')
|
||||
call job_stop(job, 'kill')
|
||||
endif
|
||||
endtry
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
" Test if socket server works in the GUI
|
||||
func Test_client_socket_server_server_gui()
|
||||
CheckNotMSWindows
|
||||
CheckFeature socketserver
|
||||
CheckFeature gui_gtk
|
||||
|
||||
let g:test_is_flaky = 1
|
||||
let cmd = GetVimCommand()
|
||||
|
||||
if cmd == ''
|
||||
throw 'GetVimCommand() failed'
|
||||
endif
|
||||
call Check_X11_Connection()
|
||||
|
||||
let name = 'VIMTESTSOCKET'
|
||||
let cmd .= ' --clientserver socket'
|
||||
let cmd .= ' --servername ' .. name
|
||||
|
||||
let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
|
||||
|
||||
call WaitForAssert({-> assert_equal("run", job_status(job))})
|
||||
call WaitForAssert({-> assert_match(name, system(cmd .. ' --serverlist'))})
|
||||
|
||||
call system(cmd .. " --remote-expr 'execute(\"gui\")'")
|
||||
|
||||
call assert_match('1', system(cmd .. " --remote-expr 'has(\"gui_running\")'"))
|
||||
call assert_match(name, system(cmd .. ' --remote-expr "v:servername"'))
|
||||
|
||||
call system(cmd .. " --remote-expr 'execute(\"qa!\")'")
|
||||
try
|
||||
call WaitForAssert({-> assert_equal("dead", job_status(job))})
|
||||
finally
|
||||
if job_status(job) != 'dead'
|
||||
call assert_report('Server did not exit')
|
||||
call job_stop(job, 'kill')
|
||||
endif
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" Test if custom paths work for socketserver
|
||||
func Test_client_socket_server_custom_path()
|
||||
CheckNotMSWindows
|
||||
CheckFeature socketserver
|
||||
CheckNotFeature x11
|
||||
|
||||
let g:test_is_flaky = 1
|
||||
let cmd = GetVimCommand()
|
||||
|
||||
if cmd == ''
|
||||
throw 'GetVimCommand() failed'
|
||||
endif
|
||||
|
||||
let name = 'VIMTESTSOCKET2'
|
||||
|
||||
let paths = ['./' .. name, '../testdir/' .. name, getcwd(-1) .. '/' .. name]
|
||||
|
||||
for path in paths
|
||||
let actual = cmd .. ' --servername ' .. path
|
||||
|
||||
let job = job_start(actual, {'stoponexit': 'kill', 'out_io': 'null'})
|
||||
|
||||
call WaitForAssert({-> assert_equal("run", job_status(job))})
|
||||
call WaitForAssert({-> assert_equal(path, glob(path))})
|
||||
|
||||
call system(actual .. " --remote-expr 'execute(\"qa!\")'")
|
||||
try
|
||||
call WaitForAssert({-> assert_equal("dead", job_status(job))})
|
||||
finally
|
||||
if job_status(job) != 'dead'
|
||||
call assert_report('Server did not exit')
|
||||
call job_stop(job, 'kill')
|
||||
endif
|
||||
endtry
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
" Uncomment this line to get a debugging log
|
||||
" call ch_logfile('channellog', 'w')
|
||||
|
||||
|
||||
@ -3,6 +3,11 @@
|
||||
source util/screendump.vim
|
||||
import './util/vim9.vim' as v9
|
||||
|
||||
" Socket backend for remote functions require the socket server to be running
|
||||
if v:servername == ""
|
||||
call remote_startserver('VIMSOCKETSERVERTEST')
|
||||
endif
|
||||
|
||||
" Test for passing too many or too few arguments to builtin functions
|
||||
func Test_internalfunc_arg_error()
|
||||
let l =<< trim END
|
||||
|
||||
@ -79,6 +79,10 @@ func Test_wayland_startup()
|
||||
call s:PreTest()
|
||||
call s:CheckXConnection()
|
||||
|
||||
if v:servername == ""
|
||||
call remote_startserver('VIMSOCKETSERVER')
|
||||
endif
|
||||
|
||||
let l:name = 'WLVIMTEST'
|
||||
let l:cmd = GetVimCommand() .. ' --servername ' .. l:name
|
||||
let l:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
|
||||
@ -372,6 +376,10 @@ func Test_wayland_autoselect_works()
|
||||
|
||||
call writefile(l:lines, 'Wltester', 'D')
|
||||
|
||||
if v:servername == ""
|
||||
call remote_startserver('VIMSOCKETSERVER')
|
||||
endif
|
||||
|
||||
let l:name = 'WLVIMTEST'
|
||||
let l:cmd = GetVimCommand() .. ' -S Wltester --servername ' .. l:name
|
||||
let l:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
|
||||
@ -415,6 +423,10 @@ func Test_no_wayland_connect_cmd_flag()
|
||||
call s:PreTest()
|
||||
call s:CheckXConnection()
|
||||
|
||||
if v:servername == ""
|
||||
call remote_startserver('VIMSOCKETSERVER')
|
||||
endif
|
||||
|
||||
let l:name = 'WLFLAGVIMTEST'
|
||||
let l:cmd = GetVimCommand() .. ' -Y --servername ' .. l:name
|
||||
let l:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
|
||||
@ -453,6 +465,10 @@ func Test_wayland_become_inactive()
|
||||
call s:PreTest()
|
||||
call s:CheckXConnection()
|
||||
|
||||
if v:servername == ""
|
||||
call remote_startserver('VIMSOCKETSERVER')
|
||||
endif
|
||||
|
||||
let l:name = 'WLLOSEVIMTEST'
|
||||
let l:cmd = GetVimCommand() .. ' --servername ' .. l:name
|
||||
let l:job = job_start(cmd, {
|
||||
@ -544,6 +560,10 @@ func Test_wayland_bad_environment()
|
||||
let l:old = $XDG_RUNTIME_DIR
|
||||
unlet $XDG_RUNTIME_DIR
|
||||
|
||||
if v:servername == ""
|
||||
call remote_startserver('VIMSOCKETSERVER')
|
||||
endif
|
||||
|
||||
let l:name = 'WLVIMTEST'
|
||||
let l:cmd = GetVimCommand() .. ' --servername ' .. l:name
|
||||
let l:job = job_start(cmd, {
|
||||
|
||||
14
src/ui.c
14
src/ui.c
@ -407,7 +407,19 @@ inchar_loop(
|
||||
|
||||
if ((resize_func != NULL && resize_func(TRUE))
|
||||
#if defined(FEAT_CLIENTSERVER) && defined(UNIX)
|
||||
|| server_waiting()
|
||||
|| (
|
||||
# ifdef FEAT_X11
|
||||
(clientserver_method == CLIENTSERVER_METHOD_X11 &&
|
||||
server_waiting())
|
||||
# endif
|
||||
# if defined(FEAT_X11) && defined(FEAT_SOCKETSERVER)
|
||||
||
|
||||
# endif
|
||||
# ifdef FEAT_SOCKETSERVER
|
||||
(clientserver_method == CLIENTSERVER_METHOD_SOCKET &&
|
||||
socket_server_waiting_accept())
|
||||
# endif
|
||||
)
|
||||
#endif
|
||||
#ifdef MESSAGE_QUEUE
|
||||
|| interrupted
|
||||
|
||||
@ -516,6 +516,11 @@ static char *(features[]) =
|
||||
"-signs",
|
||||
#endif
|
||||
"+smartindent",
|
||||
#ifdef FEAT_SOCKETSERVER
|
||||
"+socketserver",
|
||||
#else
|
||||
"-socketserver",
|
||||
#endif
|
||||
#ifdef FEAT_SODIUM
|
||||
# ifdef DYNAMIC_SODIUM
|
||||
"+sodium/dyn",
|
||||
@ -719,6 +724,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1651,
|
||||
/**/
|
||||
1650,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user