mirror of
https://github.com/vim/vim.git
synced 2025-07-25 10:54:51 -04:00
patch 7.4.1244
Problem: The channel functions don't sort together. Solution: Use a common "ch_" prefix.
This commit is contained in:
parent
fbf9c6b6c3
commit
f57969a20a
@ -1,4 +1,4 @@
|
|||||||
*eval.txt* For Vim version 7.4. Last change: 2016 Feb 01
|
*eval.txt* For Vim version 7.4. Last change: 2016 Feb 02
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -1810,6 +1810,13 @@ byteidxcomp( {expr}, {nr}) Number byte index of {nr}'th char in {expr}
|
|||||||
call( {func}, {arglist} [, {dict}])
|
call( {func}, {arglist} [, {dict}])
|
||||||
any call {func} with arguments {arglist}
|
any call {func} with arguments {arglist}
|
||||||
ceil( {expr}) Float round {expr} up
|
ceil( {expr}) Float round {expr} up
|
||||||
|
ch_close( {handle}) none close a channel
|
||||||
|
ch_open( {address}, {mode} [, {callback}])
|
||||||
|
Number open a channel
|
||||||
|
ch_sendexpr( {handle}, {expr} [, {callback}])
|
||||||
|
any send {expr} over JSON channel {handle}
|
||||||
|
ch_sendraw( {handle}, {string} [, {callback}])
|
||||||
|
any send {string} over raw channel {handle}
|
||||||
changenr() Number current change number
|
changenr() Number current change number
|
||||||
char2nr( {expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
|
char2nr( {expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
|
||||||
cindent( {lnum}) Number C indent for line {lnum}
|
cindent( {lnum}) Number C indent for line {lnum}
|
||||||
@ -1820,8 +1827,6 @@ complete_add( {expr}) Number add completion match
|
|||||||
complete_check() Number check for key typed during completion
|
complete_check() Number check for key typed during completion
|
||||||
confirm( {msg} [, {choices} [, {default} [, {type}]]])
|
confirm( {msg} [, {choices} [, {default} [, {type}]]])
|
||||||
Number number of choice picked by user
|
Number number of choice picked by user
|
||||||
connect( {address}, {mode} [, {callback}])
|
|
||||||
Number open a channel
|
|
||||||
copy( {expr}) any make a shallow copy of {expr}
|
copy( {expr}) any make a shallow copy of {expr}
|
||||||
cos( {expr}) Float cosine of {expr}
|
cos( {expr}) Float cosine of {expr}
|
||||||
cosh( {expr}) Float hyperbolic cosine of {expr}
|
cosh( {expr}) Float hyperbolic cosine of {expr}
|
||||||
@ -2029,10 +2034,6 @@ searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip} [...]]])
|
|||||||
List search for other end of start/end pair
|
List search for other end of start/end pair
|
||||||
searchpos( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
|
searchpos( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
|
||||||
List search for {pattern}
|
List search for {pattern}
|
||||||
sendexpr( {handle}, {expr} [, {callback}])
|
|
||||||
any send {expr} over JSON channel {handle}
|
|
||||||
sendraw( {handle}, {string} [, {callback}])
|
|
||||||
any send {string} over raw channel {handle}
|
|
||||||
server2client( {clientid}, {string})
|
server2client( {clientid}, {string})
|
||||||
Number send reply string
|
Number send reply string
|
||||||
serverlist() String get a list of available servers
|
serverlist() String get a list of available servers
|
||||||
@ -2666,7 +2667,10 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
|
|||||||
don't fit, a vertical layout is used anyway. For some systems
|
don't fit, a vertical layout is used anyway. For some systems
|
||||||
the horizontal layout is always used.
|
the horizontal layout is always used.
|
||||||
|
|
||||||
connect({address}, {mode} [, {callback}]) *connect()*
|
ch_close({handle}) *ch_close()*
|
||||||
|
Close channel {handle}. See |channel|.
|
||||||
|
|
||||||
|
ch_open({address}, {mode} [, {callback}]) *ch_open()*
|
||||||
Open a channel to {address}. See |channel|.
|
Open a channel to {address}. See |channel|.
|
||||||
Returns the channel handle on success. Returns a negative
|
Returns the channel handle on success. Returns a negative
|
||||||
number for failure.
|
number for failure.
|
||||||
@ -2680,6 +2684,23 @@ connect({address}, {mode} [, {callback}]) *connect()*
|
|||||||
{callback} is a function that handles received messages on the
|
{callback} is a function that handles received messages on the
|
||||||
channel. See |channel-callback|.
|
channel. See |channel-callback|.
|
||||||
|
|
||||||
|
ch_sendexpr({handle}, {expr} [, {callback}]) ch_*sendexpr()*
|
||||||
|
Send {expr} over JSON channel {handle}. See |channel-use|.
|
||||||
|
|
||||||
|
When {callback} is given returns immediately. Without
|
||||||
|
{callback} waits for a JSON response and returns the decoded
|
||||||
|
expression. When there is an error or timeout returns an
|
||||||
|
empty string.
|
||||||
|
|
||||||
|
When {callback} is zero no response is expected.
|
||||||
|
Otherwise {callback} must be a Funcref or the name of a
|
||||||
|
function. It is called when the response is received. See
|
||||||
|
|channel-callback|.
|
||||||
|
|
||||||
|
ch_sendraw({handle}, {string} [, {callback}]) *ch_sendraw()*
|
||||||
|
Send {string} over raw channel {handle}. See |channel-raw|.
|
||||||
|
Works like |ch_sendexpr()|, but does not decode the response.
|
||||||
|
|
||||||
*copy()*
|
*copy()*
|
||||||
copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't
|
copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't
|
||||||
different from using {expr} directly.
|
different from using {expr} directly.
|
||||||
@ -5615,23 +5636,6 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *searchpos()*
|
|||||||
< In this example "submatch" is 2 when a lowercase letter is
|
< In this example "submatch" is 2 when a lowercase letter is
|
||||||
found |/\l|, 3 when an uppercase letter is found |/\u|.
|
found |/\l|, 3 when an uppercase letter is found |/\u|.
|
||||||
|
|
||||||
sendexpr({handle}, {expr} [, {callback}]) *sendexpr()*
|
|
||||||
Send {expr} over JSON channel {handle}. See |channel-use|.
|
|
||||||
|
|
||||||
When {callback} is given returns immediately. Without
|
|
||||||
{callback} waits for a JSON response and returns the decoded
|
|
||||||
expression. When there is an error or timeout returns an
|
|
||||||
empty string.
|
|
||||||
|
|
||||||
When {callback} is zero no response is expected.
|
|
||||||
Otherwise {callback} must be a Funcref or the name of a
|
|
||||||
function. It is called when the response is received. See
|
|
||||||
|channel-callback|.
|
|
||||||
|
|
||||||
sendraw({handle}, {string} [, {callback}]) *sendraw()*
|
|
||||||
Send {string} over raw channel {handle}. See |channel-raw|.
|
|
||||||
Works like |sendexpr()|, but does not decode the response.
|
|
||||||
|
|
||||||
server2client( {clientid}, {string}) *server2client()*
|
server2client( {clientid}, {string}) *server2client()*
|
||||||
Send a reply string to {clientid}. The most recent {clientid}
|
Send a reply string to {clientid}. The most recent {clientid}
|
||||||
that sent a string can be retrieved with expand("<client>").
|
that sent a string can be retrieved with expand("<client>").
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
#
|
||||||
# Server that will accept connections from a Vim channel.
|
# Server that will accept connections from a Vim channel.
|
||||||
# Run this server and then in Vim you can open the channel:
|
# Run this server and then in Vim you can open the channel:
|
||||||
# :let handle = connect('localhost:8765', 'json')
|
# :let handle = ch_open('localhost:8765', 'json')
|
||||||
#
|
#
|
||||||
# Then Vim can send requests to the server:
|
# Then Vim can send requests to the server:
|
||||||
# :let response = sendexpr(handle, 'hello!')
|
# :let response = ch_sendexpr(handle, 'hello!')
|
||||||
#
|
#
|
||||||
# And you can control Vim by typing a JSON message here, e.g.:
|
# And you can control Vim by typing a JSON message here, e.g.:
|
||||||
# ["ex","echo 'hi there'"]
|
# ["ex","echo 'hi there'"]
|
||||||
#
|
#
|
||||||
|
# There is no prompt, just type a line and press Enter.
|
||||||
|
# To exit cleanly type "quit<Enter>".
|
||||||
|
#
|
||||||
# See ":help channel-demo" in Vim.
|
# See ":help channel-demo" in Vim.
|
||||||
|
#
|
||||||
|
# This requires Python 2.6 or later.
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import json
|
import json
|
||||||
|
451
src/eval.c
451
src/eval.c
@ -499,6 +499,12 @@ static void f_call(typval_T *argvars, typval_T *rettv);
|
|||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
static void f_ceil(typval_T *argvars, typval_T *rettv);
|
static void f_ceil(typval_T *argvars, typval_T *rettv);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_CHANNEL
|
||||||
|
static void f_ch_open(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_ch_close(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_ch_sendexpr(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_ch_sendraw(typval_T *argvars, typval_T *rettv);
|
||||||
|
#endif
|
||||||
static void f_changenr(typval_T *argvars, typval_T *rettv);
|
static void f_changenr(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_char2nr(typval_T *argvars, typval_T *rettv);
|
static void f_char2nr(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_cindent(typval_T *argvars, typval_T *rettv);
|
static void f_cindent(typval_T *argvars, typval_T *rettv);
|
||||||
@ -515,9 +521,6 @@ static void f_copy(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_cos(typval_T *argvars, typval_T *rettv);
|
static void f_cos(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_cosh(typval_T *argvars, typval_T *rettv);
|
static void f_cosh(typval_T *argvars, typval_T *rettv);
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
static void f_connect(typval_T *argvars, typval_T *rettv);
|
|
||||||
#endif
|
|
||||||
static void f_count(typval_T *argvars, typval_T *rettv);
|
static void f_count(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
|
static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_cursor(typval_T *argsvars, typval_T *rettv);
|
static void f_cursor(typval_T *argsvars, typval_T *rettv);
|
||||||
@ -526,9 +529,6 @@ static void f_delete(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_did_filetype(typval_T *argvars, typval_T *rettv);
|
static void f_did_filetype(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_diff_filler(typval_T *argvars, typval_T *rettv);
|
static void f_diff_filler(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
|
static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
static void f_disconnect(typval_T *argvars, typval_T *rettv);
|
|
||||||
#endif
|
|
||||||
static void f_empty(typval_T *argvars, typval_T *rettv);
|
static void f_empty(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_escape(typval_T *argvars, typval_T *rettv);
|
static void f_escape(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_eval(typval_T *argvars, typval_T *rettv);
|
static void f_eval(typval_T *argvars, typval_T *rettv);
|
||||||
@ -703,10 +703,6 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_searchpair(typval_T *argvars, typval_T *rettv);
|
static void f_searchpair(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
|
static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_searchpos(typval_T *argvars, typval_T *rettv);
|
static void f_searchpos(typval_T *argvars, typval_T *rettv);
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
static void f_sendexpr(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_sendraw(typval_T *argvars, typval_T *rettv);
|
|
||||||
#endif
|
|
||||||
static void f_server2client(typval_T *argvars, typval_T *rettv);
|
static void f_server2client(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_serverlist(typval_T *argvars, typval_T *rettv);
|
static void f_serverlist(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_setbufvar(typval_T *argvars, typval_T *rettv);
|
static void f_setbufvar(typval_T *argvars, typval_T *rettv);
|
||||||
@ -8002,6 +7998,12 @@ static struct fst
|
|||||||
{"call", 2, 3, f_call},
|
{"call", 2, 3, f_call},
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
{"ceil", 1, 1, f_ceil},
|
{"ceil", 1, 1, f_ceil},
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_CHANNEL
|
||||||
|
{"ch_close", 1, 1, f_ch_close},
|
||||||
|
{"ch_open", 2, 3, f_ch_open},
|
||||||
|
{"ch_sendexpr", 2, 3, f_ch_sendexpr},
|
||||||
|
{"ch_sendraw", 2, 3, f_ch_sendraw},
|
||||||
#endif
|
#endif
|
||||||
{"changenr", 0, 0, f_changenr},
|
{"changenr", 0, 0, f_changenr},
|
||||||
{"char2nr", 1, 2, f_char2nr},
|
{"char2nr", 1, 2, f_char2nr},
|
||||||
@ -8014,9 +8016,6 @@ static struct fst
|
|||||||
{"complete_check", 0, 0, f_complete_check},
|
{"complete_check", 0, 0, f_complete_check},
|
||||||
#endif
|
#endif
|
||||||
{"confirm", 1, 4, f_confirm},
|
{"confirm", 1, 4, f_confirm},
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
{"connect", 2, 3, f_connect},
|
|
||||||
#endif
|
|
||||||
{"copy", 1, 1, f_copy},
|
{"copy", 1, 1, f_copy},
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
{"cos", 1, 1, f_cos},
|
{"cos", 1, 1, f_cos},
|
||||||
@ -8030,9 +8029,6 @@ static struct fst
|
|||||||
{"did_filetype", 0, 0, f_did_filetype},
|
{"did_filetype", 0, 0, f_did_filetype},
|
||||||
{"diff_filler", 1, 1, f_diff_filler},
|
{"diff_filler", 1, 1, f_diff_filler},
|
||||||
{"diff_hlID", 2, 2, f_diff_hlID},
|
{"diff_hlID", 2, 2, f_diff_hlID},
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
{"disconnect", 1, 1, f_disconnect},
|
|
||||||
#endif
|
|
||||||
{"empty", 1, 1, f_empty},
|
{"empty", 1, 1, f_empty},
|
||||||
{"escape", 2, 2, f_escape},
|
{"escape", 2, 2, f_escape},
|
||||||
{"eval", 1, 1, f_eval},
|
{"eval", 1, 1, f_eval},
|
||||||
@ -8211,10 +8207,6 @@ 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},
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
{"sendexpr", 2, 3, f_sendexpr},
|
|
||||||
{"sendraw", 2, 3, f_sendraw},
|
|
||||||
#endif
|
|
||||||
{"server2client", 2, 2, f_server2client},
|
{"server2client", 2, 2, f_server2client},
|
||||||
{"serverlist", 0, 0, f_serverlist},
|
{"serverlist", 0, 0, f_serverlist},
|
||||||
{"setbufvar", 3, 3, f_setbufvar},
|
{"setbufvar", 3, 3, f_setbufvar},
|
||||||
@ -9685,6 +9677,213 @@ f_ceil(typval_T *argvars, typval_T *rettv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_CHANNEL
|
||||||
|
/*
|
||||||
|
* Get the channel index from the handle argument.
|
||||||
|
* Returns -1 if the handle is invalid or the channel is closed.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_channel_arg(typval_T *tv)
|
||||||
|
{
|
||||||
|
int ch_idx;
|
||||||
|
|
||||||
|
if (tv->v_type != VAR_NUMBER)
|
||||||
|
{
|
||||||
|
EMSG2(_(e_invarg2), get_tv_string(tv));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ch_idx = tv->vval.v_number;
|
||||||
|
|
||||||
|
if (!channel_is_open(ch_idx))
|
||||||
|
{
|
||||||
|
EMSGN(_("E906: not an open channel"), ch_idx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ch_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "ch_close()" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
int ch_idx = get_channel_arg(&argvars[0]);
|
||||||
|
|
||||||
|
if (ch_idx >= 0)
|
||||||
|
channel_close(ch_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a callback from "arg". It can be a Funcref or a function name.
|
||||||
|
* When "arg" is zero return an empty string.
|
||||||
|
* Return NULL for an invalid argument.
|
||||||
|
*/
|
||||||
|
static char_u *
|
||||||
|
get_callback(typval_T *arg)
|
||||||
|
{
|
||||||
|
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
|
||||||
|
return arg->vval.v_string;
|
||||||
|
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
||||||
|
return (char_u *)"";
|
||||||
|
EMSG(_("E999: Invalid callback argument"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "ch_open()" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_ch_open(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
char_u *address;
|
||||||
|
char_u *mode;
|
||||||
|
char_u *callback = NULL;
|
||||||
|
char_u buf1[NUMBUFLEN];
|
||||||
|
char_u *p;
|
||||||
|
int port;
|
||||||
|
int json_mode = FALSE;
|
||||||
|
|
||||||
|
/* default: fail */
|
||||||
|
rettv->vval.v_number = -1;
|
||||||
|
|
||||||
|
address = get_tv_string(&argvars[0]);
|
||||||
|
mode = get_tv_string_buf(&argvars[1], buf1);
|
||||||
|
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
callback = get_callback(&argvars[2]);
|
||||||
|
if (callback == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse address */
|
||||||
|
p = vim_strchr(address, ':');
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
EMSG2(_(e_invarg2), address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*p++ = NUL;
|
||||||
|
port = atoi((char *)p);
|
||||||
|
if (*address == NUL || port <= 0)
|
||||||
|
{
|
||||||
|
p[-1] = ':';
|
||||||
|
EMSG2(_(e_invarg2), address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse mode */
|
||||||
|
if (STRCMP(mode, "json") == 0)
|
||||||
|
json_mode = TRUE;
|
||||||
|
else if (STRCMP(mode, "raw") != 0)
|
||||||
|
{
|
||||||
|
EMSG2(_(e_invarg2), mode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rettv->vval.v_number = channel_open((char *)address, port, NULL);
|
||||||
|
if (rettv->vval.v_number >= 0)
|
||||||
|
{
|
||||||
|
channel_set_json_mode(rettv->vval.v_number, json_mode);
|
||||||
|
if (callback != NULL && *callback != NUL)
|
||||||
|
channel_set_callback(rettv->vval.v_number, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* common for "sendexpr()" and "sendraw()"
|
||||||
|
* Returns the channel index if the caller should read the response.
|
||||||
|
* Otherwise returns -1.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
send_common(typval_T *argvars, char_u *text, char *fun)
|
||||||
|
{
|
||||||
|
int ch_idx;
|
||||||
|
char_u *callback = NULL;
|
||||||
|
|
||||||
|
ch_idx = get_channel_arg(&argvars[0]);
|
||||||
|
if (ch_idx < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
callback = get_callback(&argvars[2]);
|
||||||
|
if (callback == NULL)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Set the callback or clear it. An empty callback means no callback and
|
||||||
|
* not reading the response. */
|
||||||
|
channel_set_req_callback(ch_idx,
|
||||||
|
callback != NULL && *callback == NUL ? NULL : callback);
|
||||||
|
|
||||||
|
if (channel_send(ch_idx, text, fun) == OK && callback == NULL)
|
||||||
|
return ch_idx;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "ch_sendexpr()" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
char_u *text;
|
||||||
|
typval_T *listtv;
|
||||||
|
int ch_idx;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
/* return an empty string by default */
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
rettv->vval.v_string = NULL;
|
||||||
|
|
||||||
|
id = channel_get_id();
|
||||||
|
text = json_encode_nr_expr(id, &argvars[1]);
|
||||||
|
if (text == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ch_idx = send_common(argvars, text, "sendexpr");
|
||||||
|
if (ch_idx >= 0)
|
||||||
|
{
|
||||||
|
if (channel_read_json_block(ch_idx, id, &listtv) == OK)
|
||||||
|
{
|
||||||
|
if (listtv->v_type == VAR_LIST)
|
||||||
|
{
|
||||||
|
list_T *list = listtv->vval.v_list;
|
||||||
|
|
||||||
|
if (list->lv_len == 2)
|
||||||
|
{
|
||||||
|
/* Move the item from the list and then change the type to
|
||||||
|
* avoid the value being freed. */
|
||||||
|
*rettv = list->lv_last->li_tv;
|
||||||
|
list->lv_last->li_tv.v_type = VAR_NUMBER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clear_tv(listtv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "ch_sendraw()" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_ch_sendraw(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
char_u buf[NUMBUFLEN];
|
||||||
|
char_u *text;
|
||||||
|
int ch_idx;
|
||||||
|
|
||||||
|
/* return an empty string by default */
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
rettv->vval.v_string = NULL;
|
||||||
|
|
||||||
|
text = get_tv_string_buf(&argvars[1], buf);
|
||||||
|
ch_idx = send_common(argvars, text, "sendraw");
|
||||||
|
if (ch_idx >= 0)
|
||||||
|
rettv->vval.v_string = channel_read_block(ch_idx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "changenr()" function
|
* "changenr()" function
|
||||||
*/
|
*/
|
||||||
@ -10033,84 +10232,6 @@ f_count(typval_T *argvars, typval_T *rettv)
|
|||||||
rettv->vval.v_number = n;
|
rettv->vval.v_number = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
/*
|
|
||||||
* Get a callback from "arg". It can be a Funcref or a function name.
|
|
||||||
* When "arg" is zero return an empty string.
|
|
||||||
* Return NULL for an invalid argument.
|
|
||||||
*/
|
|
||||||
static char_u *
|
|
||||||
get_callback(typval_T *arg)
|
|
||||||
{
|
|
||||||
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
|
|
||||||
return arg->vval.v_string;
|
|
||||||
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
|
||||||
return (char_u *)"";
|
|
||||||
EMSG(_("E999: Invalid callback argument"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "connect()" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_connect(typval_T *argvars, typval_T *rettv)
|
|
||||||
{
|
|
||||||
char_u *address;
|
|
||||||
char_u *mode;
|
|
||||||
char_u *callback = NULL;
|
|
||||||
char_u buf1[NUMBUFLEN];
|
|
||||||
char_u *p;
|
|
||||||
int port;
|
|
||||||
int json_mode = FALSE;
|
|
||||||
|
|
||||||
/* default: fail */
|
|
||||||
rettv->vval.v_number = -1;
|
|
||||||
|
|
||||||
address = get_tv_string(&argvars[0]);
|
|
||||||
mode = get_tv_string_buf(&argvars[1], buf1);
|
|
||||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
|
||||||
{
|
|
||||||
callback = get_callback(&argvars[2]);
|
|
||||||
if (callback == NULL)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse address */
|
|
||||||
p = vim_strchr(address, ':');
|
|
||||||
if (p == NULL)
|
|
||||||
{
|
|
||||||
EMSG2(_(e_invarg2), address);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*p++ = NUL;
|
|
||||||
port = atoi((char *)p);
|
|
||||||
if (*address == NUL || port <= 0)
|
|
||||||
{
|
|
||||||
p[-1] = ':';
|
|
||||||
EMSG2(_(e_invarg2), address);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse mode */
|
|
||||||
if (STRCMP(mode, "json") == 0)
|
|
||||||
json_mode = TRUE;
|
|
||||||
else if (STRCMP(mode, "raw") != 0)
|
|
||||||
{
|
|
||||||
EMSG2(_(e_invarg2), mode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rettv->vval.v_number = channel_open((char *)address, port, NULL);
|
|
||||||
if (rettv->vval.v_number >= 0)
|
|
||||||
{
|
|
||||||
channel_set_json_mode(rettv->vval.v_number, json_mode);
|
|
||||||
if (callback != NULL && *callback != NUL)
|
|
||||||
channel_set_callback(rettv->vval.v_number, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
|
* "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
|
||||||
*
|
*
|
||||||
@ -10349,44 +10470,6 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
/*
|
|
||||||
* Get the channel index from the handle argument.
|
|
||||||
* Returns -1 if the handle is invalid or the channel is closed.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
get_channel_arg(typval_T *tv)
|
|
||||||
{
|
|
||||||
int ch_idx;
|
|
||||||
|
|
||||||
if (tv->v_type != VAR_NUMBER)
|
|
||||||
{
|
|
||||||
EMSG2(_(e_invarg2), get_tv_string(tv));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ch_idx = tv->vval.v_number;
|
|
||||||
|
|
||||||
if (!channel_is_open(ch_idx))
|
|
||||||
{
|
|
||||||
EMSGN(_("E906: not an open channel"), ch_idx);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ch_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "disconnect()" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_disconnect(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
int ch_idx = get_channel_arg(&argvars[0]);
|
|
||||||
|
|
||||||
if (ch_idx >= 0)
|
|
||||||
channel_close(ch_idx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "empty({expr})" function
|
* "empty({expr})" function
|
||||||
*/
|
*/
|
||||||
@ -16860,102 +16943,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_CHANNEL
|
|
||||||
/*
|
|
||||||
* common for "sendexpr()" and "sendraw()"
|
|
||||||
* Returns the channel index if the caller should read the response.
|
|
||||||
* Otherwise returns -1.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
send_common(typval_T *argvars, char_u *text, char *fun)
|
|
||||||
{
|
|
||||||
int ch_idx;
|
|
||||||
char_u *callback = NULL;
|
|
||||||
|
|
||||||
ch_idx = get_channel_arg(&argvars[0]);
|
|
||||||
if (ch_idx < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
|
||||||
{
|
|
||||||
callback = get_callback(&argvars[2]);
|
|
||||||
if (callback == NULL)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* Set the callback or clear it. An empty callback means no callback and
|
|
||||||
* not reading the response. */
|
|
||||||
channel_set_req_callback(ch_idx,
|
|
||||||
callback != NULL && *callback == NUL ? NULL : callback);
|
|
||||||
|
|
||||||
if (channel_send(ch_idx, text, fun) == OK && callback == NULL)
|
|
||||||
return ch_idx;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "sendexpr()" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_sendexpr(typval_T *argvars, typval_T *rettv)
|
|
||||||
{
|
|
||||||
char_u *text;
|
|
||||||
typval_T *listtv;
|
|
||||||
int ch_idx;
|
|
||||||
int id;
|
|
||||||
|
|
||||||
/* return an empty string by default */
|
|
||||||
rettv->v_type = VAR_STRING;
|
|
||||||
rettv->vval.v_string = NULL;
|
|
||||||
|
|
||||||
id = channel_get_id();
|
|
||||||
text = json_encode_nr_expr(id, &argvars[1]);
|
|
||||||
if (text == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ch_idx = send_common(argvars, text, "sendexpr");
|
|
||||||
if (ch_idx >= 0)
|
|
||||||
{
|
|
||||||
if (channel_read_json_block(ch_idx, id, &listtv) == OK)
|
|
||||||
{
|
|
||||||
if (listtv->v_type == VAR_LIST)
|
|
||||||
{
|
|
||||||
list_T *list = listtv->vval.v_list;
|
|
||||||
|
|
||||||
if (list->lv_len == 2)
|
|
||||||
{
|
|
||||||
/* Move the item from the list and then change the type to
|
|
||||||
* avoid the value being freed. */
|
|
||||||
*rettv = list->lv_last->li_tv;
|
|
||||||
list->lv_last->li_tv.v_type = VAR_NUMBER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clear_tv(listtv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "sendraw()" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_sendraw(typval_T *argvars, typval_T *rettv)
|
|
||||||
{
|
|
||||||
char_u buf[NUMBUFLEN];
|
|
||||||
char_u *text;
|
|
||||||
int ch_idx;
|
|
||||||
|
|
||||||
/* return an empty string by default */
|
|
||||||
rettv->v_type = VAR_STRING;
|
|
||||||
rettv->vval.v_string = NULL;
|
|
||||||
|
|
||||||
text = get_tv_string_buf(&argvars[1], buf);
|
|
||||||
ch_idx = send_common(argvars, text, "sendraw");
|
|
||||||
if (ch_idx >= 0)
|
|
||||||
rettv->vval.v_string = channel_read_block(ch_idx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
f_server2client(typval_T *argvars UNUSED, typval_T *rettv)
|
f_server2client(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
{
|
{
|
||||||
|
@ -742,6 +742,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1244,
|
||||||
/**/
|
/**/
|
||||||
1243,
|
1243,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user