mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #2331 from splinterofchaos/serverlisten
vimL: serverlisten({addr}), list(), and stop({addr})
This commit is contained in:
commit
b47ea5fcde
@ -58,6 +58,7 @@ check_function_exists(setenv HAVE_SETENV)
|
|||||||
if(NOT HAVE_SETENV)
|
if(NOT HAVE_SETENV)
|
||||||
message(SEND_ERROR "setenv() function not found on your system.")
|
message(SEND_ERROR "setenv() function not found on your system.")
|
||||||
endif()
|
endif()
|
||||||
|
check_function_exists(unsetenv HAVE_UNSETENV)
|
||||||
check_function_exists(setpgid HAVE_SETPGID)
|
check_function_exists(setpgid HAVE_SETPGID)
|
||||||
check_function_exists(setsid HAVE_SETSID)
|
check_function_exists(setsid HAVE_SETSID)
|
||||||
check_function_exists(sigaction HAVE_SIGACTION)
|
check_function_exists(sigaction HAVE_SIGACTION)
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
// TODO: add proper cmake check
|
// TODO: add proper cmake check
|
||||||
// #define HAVE_SELINUX 1
|
// #define HAVE_SELINUX 1
|
||||||
#cmakedefine HAVE_SETENV
|
#cmakedefine HAVE_SETENV
|
||||||
|
#cmakedefine HAVE_UNSETENV
|
||||||
#cmakedefine HAVE_SETPGID
|
#cmakedefine HAVE_SETPGID
|
||||||
#cmakedefine HAVE_SETSID
|
#cmakedefine HAVE_SETSID
|
||||||
#cmakedefine HAVE_SIGACTION
|
#cmakedefine HAVE_SIGACTION
|
||||||
|
@ -5373,13 +5373,25 @@ server2client( {clientid}, {string}) *server2client()*
|
|||||||
:echo server2client(expand("<client>"), "HELLO")
|
:echo server2client(expand("<client>"), "HELLO")
|
||||||
<
|
<
|
||||||
serverlist() *serverlist()*
|
serverlist() *serverlist()*
|
||||||
Return a list of available server names, one per line.
|
Returns a list of available server names in a list.
|
||||||
When there are no servers or the information is not available
|
When there are no servers an empty string is returned.
|
||||||
an empty string is returned. See also |clientserver|.
|
|
||||||
{only available when compiled with the |+clientserver| feature}
|
|
||||||
Example: >
|
Example: >
|
||||||
:echo serverlist()
|
:echo serverlist()
|
||||||
<
|
<
|
||||||
|
serverlisten([{address}]) *serverlisten()*
|
||||||
|
Opens a Unix or TCP socket at {address} for clients to connect
|
||||||
|
to and returns {address}. If no address is given, it is
|
||||||
|
equivalent to >
|
||||||
|
:call serverlisten(tempname())
|
||||||
|
< If |$NVIM_LISTEN_ADDRESS| is not set, it will be set to
|
||||||
|
{address}.
|
||||||
|
|
||||||
|
serverstop({address}) *serverstop()*
|
||||||
|
Closes the Unix or TCP socket at {address}. Does nothing if
|
||||||
|
{address} is empty, or does not refer to a server. If
|
||||||
|
{address} equals |$NVIM_LISTEN_ADDRESS|, the listen address
|
||||||
|
will be unset.
|
||||||
|
|
||||||
setbufvar({expr}, {varname}, {val}) *setbufvar()*
|
setbufvar({expr}, {varname}, {val}) *setbufvar()*
|
||||||
Set option or local variable {varname} in buffer {expr} to
|
Set option or local variable {varname} in buffer {expr} to
|
||||||
{val}.
|
{val}.
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
#include "nvim/os/rstream_defs.h"
|
#include "nvim/os/rstream_defs.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/msgpack_rpc/channel.h"
|
#include "nvim/msgpack_rpc/channel.h"
|
||||||
|
#include "nvim/msgpack_rpc/server.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/api/vim.h"
|
#include "nvim/api/vim.h"
|
||||||
#include "nvim/os/dl.h"
|
#include "nvim/os/dl.h"
|
||||||
@ -6605,6 +6606,9 @@ static struct fst {
|
|||||||
{"searchpair", 3, 7, f_searchpair},
|
{"searchpair", 3, 7, f_searchpair},
|
||||||
{"searchpairpos", 3, 7, f_searchpairpos},
|
{"searchpairpos", 3, 7, f_searchpairpos},
|
||||||
{"searchpos", 1, 4, f_searchpos},
|
{"searchpos", 1, 4, f_searchpos},
|
||||||
|
{"serverlist", 0, 0, f_serverlist},
|
||||||
|
{"serverstart", 0, 1, f_serverstart},
|
||||||
|
{"serverstop", 1, 1, f_serverstop},
|
||||||
{"setbufvar", 3, 3, f_setbufvar},
|
{"setbufvar", 3, 3, f_setbufvar},
|
||||||
{"setcmdpos", 1, 1, f_setcmdpos},
|
{"setcmdpos", 1, 1, f_setcmdpos},
|
||||||
{"setline", 2, 2, f_setline},
|
{"setline", 2, 2, f_setline},
|
||||||
@ -13292,6 +13296,69 @@ static void f_searchpos(typval_T *argvars, typval_T *rettv)
|
|||||||
list_append_number(rettv->vval.v_list, (varnumber_T)n);
|
list_append_number(rettv->vval.v_list, (varnumber_T)n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// "serverlist()" function
|
||||||
|
static void f_serverlist(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
char **addrs = server_address_list(&n);
|
||||||
|
|
||||||
|
// Copy addrs into a linked list.
|
||||||
|
list_T *l = rettv_list_alloc(rettv);
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
listitem_T *li = listitem_alloc();
|
||||||
|
li->li_tv.v_type = VAR_STRING;
|
||||||
|
li->li_tv.v_lock = 0;
|
||||||
|
li->li_tv.vval.v_string = (char_u *) addrs[i];
|
||||||
|
list_append(l, li);
|
||||||
|
}
|
||||||
|
xfree(addrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "serverstart()" function
|
||||||
|
static void f_serverstart(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
rettv->vval.v_string = NULL; // Will hold the address of the new server.
|
||||||
|
|
||||||
|
if (check_restricted() || check_secure()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user supplied an address, use it, otherwise use a temp.
|
||||||
|
if (argvars[0].v_type != VAR_UNKNOWN) {
|
||||||
|
if (argvars[0].v_type != VAR_STRING) {
|
||||||
|
EMSG(_(e_invarg));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
rettv->vval.v_string = vim_strsave(get_tv_string(argvars));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rettv->vval.v_string = vim_tempname();
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = server_start((char *) rettv->vval.v_string);
|
||||||
|
if (result != 0) {
|
||||||
|
EMSG2("Failed to start server: %s", uv_strerror(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// "serverstop()" function
|
||||||
|
static void f_serverstop(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
if (check_restricted() || check_secure()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvars[0].v_type == VAR_UNKNOWN || argvars[0].v_type != VAR_STRING) {
|
||||||
|
EMSG(_(e_invarg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvars[0].vval.v_string) {
|
||||||
|
server_stop((char *) argvars[0].vval.v_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "setbufvar()" function
|
* "setbufvar()" function
|
||||||
*/
|
*/
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
#include "nvim/msgpack_rpc/server.h"
|
#include "nvim/msgpack_rpc/server.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
|
#include "nvim/garray.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/log.h"
|
#include "nvim/log.h"
|
||||||
#include "nvim/tempfile.h"
|
#include "nvim/tempfile.h"
|
||||||
#include "nvim/map.h"
|
|
||||||
#include "nvim/path.h"
|
#include "nvim/path.h"
|
||||||
|
|
||||||
#define MAX_CONNECTIONS 32
|
#define MAX_CONNECTIONS 32
|
||||||
@ -27,6 +27,9 @@ typedef enum {
|
|||||||
} ServerType;
|
} ServerType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
// The address of a pipe, or string value of a tcp address.
|
||||||
|
char addr[ADDRESS_MAX_SIZE];
|
||||||
|
|
||||||
// Type of the union below
|
// Type of the union below
|
||||||
ServerType type;
|
ServerType type;
|
||||||
|
|
||||||
@ -38,12 +41,11 @@ typedef struct {
|
|||||||
} tcp;
|
} tcp;
|
||||||
struct {
|
struct {
|
||||||
uv_pipe_t handle;
|
uv_pipe_t handle;
|
||||||
char addr[ADDRESS_MAX_SIZE];
|
|
||||||
} pipe;
|
} pipe;
|
||||||
} socket;
|
} socket;
|
||||||
} Server;
|
} Server;
|
||||||
|
|
||||||
static PMap(cstr_t) *servers = NULL;
|
static garray_T servers = GA_EMPTY_INIT_VALUE;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "msgpack_rpc/server.c.generated.h"
|
# include "msgpack_rpc/server.c.generated.h"
|
||||||
@ -52,33 +54,40 @@ static PMap(cstr_t) *servers = NULL;
|
|||||||
/// Initializes the module
|
/// Initializes the module
|
||||||
bool server_init(void)
|
bool server_init(void)
|
||||||
{
|
{
|
||||||
servers = pmap_new(cstr_t)();
|
ga_init(&servers, sizeof(Server *), 1);
|
||||||
|
|
||||||
if (!os_getenv(LISTEN_ADDRESS_ENV_VAR)) {
|
bool must_free = false;
|
||||||
char *listen_address = (char *)vim_tempname();
|
const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
|
||||||
os_setenv(LISTEN_ADDRESS_ENV_VAR, listen_address, 1);
|
if (listen_address == NULL || *listen_address == NUL) {
|
||||||
xfree(listen_address);
|
must_free = true;
|
||||||
|
listen_address = (char *)vim_tempname();
|
||||||
}
|
}
|
||||||
|
|
||||||
return server_start((char *)os_getenv(LISTEN_ADDRESS_ENV_VAR)) == 0;
|
bool ok = (server_start(listen_address) == 0);
|
||||||
|
if (must_free) {
|
||||||
|
xfree((char *) listen_address);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the file handle from a server.
|
||||||
|
static uv_handle_t *server_handle(Server *server)
|
||||||
|
{
|
||||||
|
return server->type == kServerTypeTcp
|
||||||
|
? (uv_handle_t *)&server->socket.tcp.handle
|
||||||
|
: (uv_handle_t *) &server->socket.pipe.handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Teardown a single server
|
||||||
|
static void server_close_cb(Server **server)
|
||||||
|
{
|
||||||
|
uv_close(server_handle(*server), free_server);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Teardown the server module
|
/// Teardown the server module
|
||||||
void server_teardown(void)
|
void server_teardown(void)
|
||||||
{
|
{
|
||||||
if (!servers) {
|
GA_DEEP_CLEAR(&servers, Server *, server_close_cb);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Server *server;
|
|
||||||
|
|
||||||
map_foreach_value(servers, server, {
|
|
||||||
if (server->type == kServerTypeTcp) {
|
|
||||||
uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server);
|
|
||||||
} else {
|
|
||||||
uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts listening on arbitrary tcp/unix addresses specified by
|
/// Starts listening on arbitrary tcp/unix addresses specified by
|
||||||
@ -106,9 +115,11 @@ int server_start(const char *endpoint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the server already exists
|
// Check if the server already exists
|
||||||
if (pmap_has(cstr_t)(servers, addr)) {
|
for (int i = 0; i < servers.ga_len; i++) {
|
||||||
ELOG("Already listening on %s", addr);
|
if (strcmp(addr, ((Server **)servers.ga_data)[i]->addr) == 0) {
|
||||||
return 1;
|
ELOG("Already listening on %s", addr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerType server_type = kServerTypeTcp;
|
ServerType server_type = kServerTypeTcp;
|
||||||
@ -154,6 +165,8 @@ int server_start(const char *endpoint)
|
|||||||
int result;
|
int result;
|
||||||
uv_stream_t *stream = NULL;
|
uv_stream_t *stream = NULL;
|
||||||
|
|
||||||
|
xstrlcpy(server->addr, addr, sizeof(server->addr));
|
||||||
|
|
||||||
if (server_type == kServerTypeTcp) {
|
if (server_type == kServerTypeTcp) {
|
||||||
// Listen on tcp address/port
|
// Listen on tcp address/port
|
||||||
uv_tcp_init(uv_default_loop(), &server->socket.tcp.handle);
|
uv_tcp_init(uv_default_loop(), &server->socket.tcp.handle);
|
||||||
@ -163,10 +176,8 @@ int server_start(const char *endpoint)
|
|||||||
stream = (uv_stream_t *)&server->socket.tcp.handle;
|
stream = (uv_stream_t *)&server->socket.tcp.handle;
|
||||||
} else {
|
} else {
|
||||||
// Listen on named pipe or unix socket
|
// Listen on named pipe or unix socket
|
||||||
xstrlcpy(server->socket.pipe.addr, addr, sizeof(server->socket.pipe.addr));
|
|
||||||
uv_pipe_init(uv_default_loop(), &server->socket.pipe.handle, 0);
|
uv_pipe_init(uv_default_loop(), &server->socket.pipe.handle, 0);
|
||||||
result = uv_pipe_bind(&server->socket.pipe.handle,
|
result = uv_pipe_bind(&server->socket.pipe.handle, server->addr);
|
||||||
server->socket.pipe.addr);
|
|
||||||
stream = (uv_stream_t *)&server->socket.pipe.handle;
|
stream = (uv_stream_t *)&server->socket.pipe.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,9 +204,17 @@ int server_start(const char *endpoint)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update $NVIM_LISTEN_ADDRESS, if not set.
|
||||||
|
const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
|
||||||
|
if (listen_address == NULL || *listen_address == NUL) {
|
||||||
|
os_setenv(LISTEN_ADDRESS_ENV_VAR, addr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
server->type = server_type;
|
server->type = server_type;
|
||||||
// Add the server to the hash table
|
|
||||||
pmap_put(cstr_t)(servers, addr, server);
|
// Add the server to the list.
|
||||||
|
ga_grow(&servers, 1);
|
||||||
|
((Server **)servers.ga_data)[servers.ga_len++] = server;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -211,18 +230,49 @@ void server_stop(char *endpoint)
|
|||||||
// Trim to `ADDRESS_MAX_SIZE`
|
// Trim to `ADDRESS_MAX_SIZE`
|
||||||
xstrlcpy(addr, endpoint, sizeof(addr));
|
xstrlcpy(addr, endpoint, sizeof(addr));
|
||||||
|
|
||||||
if ((server = pmap_get(cstr_t)(servers, addr)) == NULL) {
|
int i = 0; // The index of the server whose address equals addr.
|
||||||
|
for (; i < servers.ga_len; i++) {
|
||||||
|
server = ((Server **)servers.ga_data)[i];
|
||||||
|
if (strcmp(addr, server->addr) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == servers.ga_len) {
|
||||||
ELOG("Not listening on %s", addr);
|
ELOG("Not listening on %s", addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server->type == kServerTypeTcp) {
|
// If we are invalidating the listen address, unset it.
|
||||||
uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server);
|
const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
|
||||||
} else {
|
if (listen_address && strcmp(addr, listen_address) == 0) {
|
||||||
uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
|
os_unsetenv(LISTEN_ADDRESS_ENV_VAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
pmap_del(cstr_t)(servers, addr);
|
uv_close(server_handle(server), free_server);
|
||||||
|
|
||||||
|
// Remove this server from the list by swapping it with the last item.
|
||||||
|
if (i != servers.ga_len - 1) {
|
||||||
|
((Server **)servers.ga_data)[i] =
|
||||||
|
((Server **)servers.ga_data)[servers.ga_len - 1];
|
||||||
|
}
|
||||||
|
servers.ga_len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an allocated array of server addresses.
|
||||||
|
/// @param[out] size The size of the returned array.
|
||||||
|
char **server_address_list(size_t *size)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
if ((*size = (size_t) servers.ga_len) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **addrs = xcalloc((size_t) servers.ga_len, sizeof(const char **));
|
||||||
|
for (int i = 0; i < servers.ga_len; i++) {
|
||||||
|
addrs[i] = xstrdup(((Server **)servers.ga_data)[i]->addr);
|
||||||
|
}
|
||||||
|
return addrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connection_cb(uv_stream_t *server, int status)
|
static void connection_cb(uv_stream_t *server, int status)
|
||||||
|
@ -37,6 +37,19 @@ int os_setenv(const char *name, const char *value, int overwrite)
|
|||||||
return setenv(name, value, overwrite);
|
return setenv(name, value, overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unset environment variable
|
||||||
|
///
|
||||||
|
/// For systems where unsetenv() is not available the value will be set as an
|
||||||
|
/// empty string
|
||||||
|
int os_unsetenv(const char *name)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_UNSETENV
|
||||||
|
return unsetenv(name);
|
||||||
|
#else
|
||||||
|
return os_setenv(name, "", 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
char *os_getenvname_at_index(size_t index)
|
char *os_getenvname_at_index(size_t index)
|
||||||
{
|
{
|
||||||
# if defined(HAVE__NSGETENVIRON)
|
# if defined(HAVE__NSGETENVIRON)
|
||||||
|
42
test/functional/server/server_spec.lua
Normal file
42
test/functional/server/server_spec.lua
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
local helpers = require('test.functional.helpers')
|
||||||
|
local nvim, eq, neq, ok, eval
|
||||||
|
= helpers.nvim, helpers.eq, helpers.neq, helpers.ok, helpers.eval
|
||||||
|
local clear = helpers.clear
|
||||||
|
|
||||||
|
describe('server*() functions', function()
|
||||||
|
before_each(clear)
|
||||||
|
|
||||||
|
it('set $NVIM_LISTEN_ADDRESS on first serverstart()', function()
|
||||||
|
-- Ensure the listen address is unset.
|
||||||
|
nvim('command', 'let $NVIM_LISTEN_ADDRESS = ""')
|
||||||
|
nvim('command', 'let s = serverstart()')
|
||||||
|
eq(1, eval('$NVIM_LISTEN_ADDRESS == s'))
|
||||||
|
nvim('command', 'call serverstop(s)')
|
||||||
|
eq(0, eval('$NVIM_LISTEN_ADDRESS == s'))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('let the user retrieve the list of servers', function()
|
||||||
|
-- There should already be at least one server.
|
||||||
|
local n = eval('len(serverlist())')
|
||||||
|
|
||||||
|
-- Add a few
|
||||||
|
local servs = {'should-not-exist', 'another-one-that-shouldnt'}
|
||||||
|
for _, s in ipairs(servs) do
|
||||||
|
eq(s, eval('serverstart("'..s..'")'))
|
||||||
|
end
|
||||||
|
|
||||||
|
local new_servs = eval('serverlist()')
|
||||||
|
|
||||||
|
-- Exactly #servs servers should be added.
|
||||||
|
eq(n + #servs, #new_servs)
|
||||||
|
-- The new servers should be at the end of the list.
|
||||||
|
for i = 1, #servs do
|
||||||
|
eq(servs[i], new_servs[i + n])
|
||||||
|
nvim('command', 'call serverstop("'..servs[i]..'")')
|
||||||
|
end
|
||||||
|
-- After calling serverstop() on the new servers, they should no longer be
|
||||||
|
-- in the list.
|
||||||
|
eq(n, eval('len(serverlist())'))
|
||||||
|
end)
|
||||||
|
end)
|
@ -3,6 +3,7 @@ local helpers = require('test.unit.helpers')
|
|||||||
local cimport = helpers.cimport
|
local cimport = helpers.cimport
|
||||||
local internalize = helpers.internalize
|
local internalize = helpers.internalize
|
||||||
local eq = helpers.eq
|
local eq = helpers.eq
|
||||||
|
local neq = helpers.neq
|
||||||
local ffi = helpers.ffi
|
local ffi = helpers.ffi
|
||||||
local lib = helpers.lib
|
local lib = helpers.lib
|
||||||
local cstr = helpers.cstr
|
local cstr = helpers.cstr
|
||||||
@ -21,6 +22,10 @@ describe('env function', function()
|
|||||||
return env.os_setenv((to_cstr(name)), (to_cstr(value)), override)
|
return env.os_setenv((to_cstr(name)), (to_cstr(value)), override)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function os_unsetenv(name, value, override)
|
||||||
|
return env.os_unsetenv((to_cstr(name)))
|
||||||
|
end
|
||||||
|
|
||||||
function os_getenv(name)
|
function os_getenv(name)
|
||||||
local rval = env.os_getenv((to_cstr(name)))
|
local rval = env.os_getenv((to_cstr(name)))
|
||||||
if rval ~= NULL then
|
if rval ~= NULL then
|
||||||
@ -68,6 +73,18 @@ describe('env function', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('os_unsetenv', function()
|
||||||
|
it('unsets environment variable', function()
|
||||||
|
local name = 'TEST_UNSETENV'
|
||||||
|
local value = 'TESTVALUE'
|
||||||
|
os_setenv(name, value, 1)
|
||||||
|
os_unsetenv(name)
|
||||||
|
neq(os_getenv(name), value)
|
||||||
|
-- Depending on the platform the var might be unset or set as ''
|
||||||
|
assert.True(os_getenv(name) == nil or os_getenv(name) == '')
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
describe('os_getenvname_at_index', function()
|
describe('os_getenvname_at_index', function()
|
||||||
it('returns names of environment variables', function()
|
it('returns names of environment variables', function()
|
||||||
local test_name = 'NEOVIM_UNIT_TEST_GETENVNAME_AT_INDEX_1N'
|
local test_name = 'NEOVIM_UNIT_TEST_GETENVNAME_AT_INDEX_1N'
|
||||||
|
Loading…
Reference in New Issue
Block a user