forked from aniani/vim
patch 7.4.1624
Problem: Can't get info about a channel. Solution: Add ch_info().
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 15
|
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 20
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -753,7 +753,12 @@ recursively. Ignoring case means case is ignored when comparing item values.
|
|||||||
|
|
||||||
*E693* *E694*
|
*E693* *E694*
|
||||||
A |Funcref| can only be compared with a |Funcref| and only "equal" and "not
|
A |Funcref| can only be compared with a |Funcref| and only "equal" and "not
|
||||||
equal" can be used. Case is never ignored.
|
equal" can be used. Case is never ignored. Whether arguments or a Dictionary
|
||||||
|
are bound (with a partial) is ignored. This is so that when a function is
|
||||||
|
made a member of a Dictionary it is still considered to be the same function.
|
||||||
|
To compare partials to see if they bind the same argument and Dictionary
|
||||||
|
values use string(): >
|
||||||
|
echo string(Partial1) == string(Partial2)
|
||||||
|
|
||||||
When using "is" or "isnot" with a |List| or a |Dictionary| this checks if the
|
When using "is" or "isnot" with a |List| or a |Dictionary| this checks if the
|
||||||
expressions are referring to the same |List| or |Dictionary| instance. A copy
|
expressions are referring to the same |List| or |Dictionary| instance. A copy
|
||||||
@@ -1822,6 +1827,7 @@ ch_evalraw( {handle}, {string} [, {options}])
|
|||||||
any evaluate {string} on raw {handle}
|
any evaluate {string} on raw {handle}
|
||||||
ch_getbufnr( {handle}, {what}) Number get buffer number for {handle}/{what}
|
ch_getbufnr( {handle}, {what}) Number get buffer number for {handle}/{what}
|
||||||
ch_getjob( {channel}) Job get the Job of {channel}
|
ch_getjob( {channel}) Job get the Job of {channel}
|
||||||
|
ch_info( {handle}) String info about channel {handle}
|
||||||
ch_log( {msg} [, {handle}]) none write {msg} in the channel log file
|
ch_log( {msg} [, {handle}]) none write {msg} in the channel log file
|
||||||
ch_logfile( {fname} [, {mode}]) none start logging channel activity
|
ch_logfile( {fname} [, {mode}]) none start logging channel activity
|
||||||
ch_open( {address} [, {options}]) Channel open a channel to {address}
|
ch_open( {address} [, {options}]) Channel open a channel to {address}
|
||||||
@@ -1832,7 +1838,7 @@ ch_sendexpr( {handle}, {expr} [, {options}])
|
|||||||
ch_sendraw( {handle}, {string} [, {options}])
|
ch_sendraw( {handle}, {string} [, {options}])
|
||||||
any send {string} over raw {handle}
|
any send {string} over raw {handle}
|
||||||
ch_setoptions( {handle}, {options}) none set options for {handle}
|
ch_setoptions( {handle}, {options}) none set options for {handle}
|
||||||
ch_status( {handle}) String status of {handle}
|
ch_status( {handle}) String status of 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}
|
||||||
@@ -2759,6 +2765,32 @@ ch_getjob({channel}) *ch_getjob()*
|
|||||||
{only available when compiled with the |+channel| and
|
{only available when compiled with the |+channel| and
|
||||||
|+job| features}
|
|+job| features}
|
||||||
|
|
||||||
|
ch_info({handle}) *ch_info()*
|
||||||
|
Returns a Dictionary with information about {handle}. The
|
||||||
|
items are:
|
||||||
|
"id" number of the channel
|
||||||
|
"status" "open" (any part is open) or "closed"
|
||||||
|
When opened with ch_open():
|
||||||
|
"hostname" the hostname of the address
|
||||||
|
"port" the port of the address
|
||||||
|
"sock_status" "open" or "closed"
|
||||||
|
"sock_mode" "NL", "RAW", "JSON" or "JS"
|
||||||
|
"sock_io" "socket"
|
||||||
|
"sock_timeout" timeout in msec
|
||||||
|
When opened with job_start():
|
||||||
|
"out_status" "open" or "closed"
|
||||||
|
"out_mode" "NL", "RAW", "JSON" or "JS"
|
||||||
|
"out_io" "null", "pipe", "file" or "buffer"
|
||||||
|
"out_timeout" timeout in msec
|
||||||
|
"err_status" "open" or "closed"
|
||||||
|
"err_mode" "NL", "RAW", "JSON" or "JS"
|
||||||
|
"err_io" "out", "null", "pipe", "file" or "buffer"
|
||||||
|
"err_timeout" timeout in msec
|
||||||
|
"in_status" "open" or "closed"
|
||||||
|
"in_mode" "NL", "RAW", "JSON" or "JS"
|
||||||
|
"in_io" "null", "pipe", "file" or "buffer"
|
||||||
|
"in_timeout" timeout in msec
|
||||||
|
|
||||||
ch_log({msg} [, {handle}]) *ch_log()*
|
ch_log({msg} [, {handle}]) *ch_log()*
|
||||||
Write {msg} in the channel log file, if it was opened with
|
Write {msg} in the channel log file, if it was opened with
|
||||||
|ch_logfile()|.
|
|ch_logfile()|.
|
||||||
@@ -3594,6 +3626,18 @@ function({name} [, {arglist}] [, {dict}])
|
|||||||
< Invokes the function as with: >
|
< Invokes the function as with: >
|
||||||
call Callback('one', 'two', 'name')
|
call Callback('one', 'two', 'name')
|
||||||
|
|
||||||
|
< The function() call can be nested to add more arguments to the
|
||||||
|
Funcref. The extra arguments are appended to the list of
|
||||||
|
arguments. Example: >
|
||||||
|
func Callback(arg1, arg2, name)
|
||||||
|
...
|
||||||
|
let Func = function('Callback', ['one'])
|
||||||
|
let Func2 = function(Func, ['two'])
|
||||||
|
...
|
||||||
|
call Func2('name')
|
||||||
|
< Invokes the function as with: >
|
||||||
|
call Callback('one', 'two', 'name')
|
||||||
|
|
||||||
< The Dictionary is only useful when calling a "dict" function.
|
< The Dictionary is only useful when calling a "dict" function.
|
||||||
In that case the {dict} is passed in as "self". Example: >
|
In that case the {dict} is passed in as "self". Example: >
|
||||||
function Callback() dict
|
function Callback() dict
|
||||||
@@ -7050,6 +7094,10 @@ timer_start({time}, {callback} [, {options}])
|
|||||||
intervals.
|
intervals.
|
||||||
{only available when compiled with the |+timers| feature}
|
{only available when compiled with the |+timers| feature}
|
||||||
|
|
||||||
|
timer_stop({timer}) *timer_stop()*
|
||||||
|
Stop a timer. {timer} is an ID returned by timer_start().
|
||||||
|
The timer callback will no longer be invoked.
|
||||||
|
|
||||||
tolower({expr}) *tolower()*
|
tolower({expr}) *tolower()*
|
||||||
The result is a copy of the String given, with all uppercase
|
The result is a copy of the String given, with all uppercase
|
||||||
characters turned into lowercase (just like applying |gu| to
|
characters turned into lowercase (just like applying |gu| to
|
||||||
|
@@ -838,6 +838,8 @@ channel_open(
|
|||||||
|
|
||||||
channel->CH_SOCK_FD = (sock_T)sd;
|
channel->CH_SOCK_FD = (sock_T)sd;
|
||||||
channel->ch_nb_close_cb = nb_close_cb;
|
channel->ch_nb_close_cb = nb_close_cb;
|
||||||
|
channel->ch_hostname = (char *)vim_strsave((char_u *)hostname);
|
||||||
|
channel->ch_port = port_in;
|
||||||
|
|
||||||
#ifdef FEAT_GUI
|
#ifdef FEAT_GUI
|
||||||
channel_gui_register_one(channel, PART_SOCK);
|
channel_gui_register_one(channel, PART_SOCK);
|
||||||
@@ -1138,6 +1140,10 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
|
|||||||
ch_logs(channel, "writing err to buffer '%s'",
|
ch_logs(channel, "writing err to buffer '%s'",
|
||||||
(char *)channel->ch_part[PART_ERR].ch_buffer->b_ffname);
|
(char *)channel->ch_part[PART_ERR].ch_buffer->b_ffname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT];
|
||||||
|
channel->ch_part[PART_ERR].ch_io = opt->jo_io[PART_ERR];
|
||||||
|
channel->ch_part[PART_IN].ch_io = opt->jo_io[PART_IN];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2088,6 +2094,69 @@ channel_status(channel_T *channel)
|
|||||||
return "closed";
|
return "closed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
channel_part_info(channel_T *channel, dict_T *dict, char *name, int part)
|
||||||
|
{
|
||||||
|
chanpart_T *chanpart = &channel->ch_part[part];
|
||||||
|
char namebuf[20];
|
||||||
|
int tail;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
STRCPY(namebuf, name);
|
||||||
|
STRCAT(namebuf, "_");
|
||||||
|
tail = STRLEN(namebuf);
|
||||||
|
|
||||||
|
STRCPY(namebuf + tail, "status");
|
||||||
|
dict_add_nr_str(dict, namebuf, 0,
|
||||||
|
(char_u *)(chanpart->ch_fd == INVALID_FD ? "closed" : "open"));
|
||||||
|
|
||||||
|
STRCPY(namebuf + tail, "mode");
|
||||||
|
switch (chanpart->ch_mode)
|
||||||
|
{
|
||||||
|
case MODE_NL: s = "NL"; break;
|
||||||
|
case MODE_RAW: s = "RAW"; break;
|
||||||
|
case MODE_JSON: s = "JSON"; break;
|
||||||
|
case MODE_JS: s = "JS"; break;
|
||||||
|
}
|
||||||
|
dict_add_nr_str(dict, namebuf, 0, (char_u *)s);
|
||||||
|
|
||||||
|
STRCPY(namebuf + tail, "io");
|
||||||
|
if (part == PART_SOCK)
|
||||||
|
s = "socket";
|
||||||
|
else switch (chanpart->ch_io)
|
||||||
|
{
|
||||||
|
case JIO_NULL: s = "null"; break;
|
||||||
|
case JIO_PIPE: s = "pipe"; break;
|
||||||
|
case JIO_FILE: s = "file"; break;
|
||||||
|
case JIO_BUFFER: s = "buffer"; break;
|
||||||
|
case JIO_OUT: s = "out"; break;
|
||||||
|
}
|
||||||
|
dict_add_nr_str(dict, namebuf, 0, (char_u *)s);
|
||||||
|
|
||||||
|
STRCPY(namebuf + tail, "timeout");
|
||||||
|
dict_add_nr_str(dict, namebuf, chanpart->ch_timeout, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
channel_info(channel_T *channel, dict_T *dict)
|
||||||
|
{
|
||||||
|
dict_add_nr_str(dict, "id", channel->ch_id, NULL);
|
||||||
|
dict_add_nr_str(dict, "status", 0, (char_u *)channel_status(channel));
|
||||||
|
|
||||||
|
if (channel->ch_hostname != NULL)
|
||||||
|
{
|
||||||
|
dict_add_nr_str(dict, "hostname", 0, (char_u *)channel->ch_hostname);
|
||||||
|
dict_add_nr_str(dict, "port", channel->ch_port, NULL);
|
||||||
|
channel_part_info(channel, dict, "sock", PART_SOCK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
channel_part_info(channel, dict, "out", PART_OUT);
|
||||||
|
channel_part_info(channel, dict, "err", PART_ERR);
|
||||||
|
channel_part_info(channel, dict, "in", PART_IN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close channel "channel".
|
* Close channel "channel".
|
||||||
* Trigger the close callback if "invoke_close_cb" is TRUE.
|
* Trigger the close callback if "invoke_close_cb" is TRUE.
|
||||||
@@ -2195,6 +2264,8 @@ channel_clear_one(channel_T *channel, int part)
|
|||||||
channel_clear(channel_T *channel)
|
channel_clear(channel_T *channel)
|
||||||
{
|
{
|
||||||
ch_log(channel, "Clearing channel");
|
ch_log(channel, "Clearing channel");
|
||||||
|
vim_free(channel->ch_hostname);
|
||||||
|
channel->ch_hostname = NULL;
|
||||||
channel_clear_one(channel, PART_SOCK);
|
channel_clear_one(channel, PART_SOCK);
|
||||||
channel_clear_one(channel, PART_OUT);
|
channel_clear_one(channel, PART_OUT);
|
||||||
channel_clear_one(channel, PART_ERR);
|
channel_clear_one(channel, PART_ERR);
|
||||||
|
14
src/eval.c
14
src/eval.c
@@ -501,6 +501,7 @@ static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_ch_evalraw(typval_T *argvars, typval_T *rettv);
|
static void f_ch_evalraw(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv);
|
static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_ch_getjob(typval_T *argvars, typval_T *rettv);
|
static void f_ch_getjob(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_ch_info(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_ch_log(typval_T *argvars, typval_T *rettv);
|
static void f_ch_log(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_ch_logfile(typval_T *argvars, typval_T *rettv);
|
static void f_ch_logfile(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_ch_open(typval_T *argvars, typval_T *rettv);
|
static void f_ch_open(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -8141,6 +8142,7 @@ static struct fst
|
|||||||
{"ch_evalraw", 2, 3, f_ch_evalraw},
|
{"ch_evalraw", 2, 3, f_ch_evalraw},
|
||||||
{"ch_getbufnr", 2, 2, f_ch_getbufnr},
|
{"ch_getbufnr", 2, 2, f_ch_getbufnr},
|
||||||
{"ch_getjob", 1, 1, f_ch_getjob},
|
{"ch_getjob", 1, 1, f_ch_getjob},
|
||||||
|
{"ch_info", 1, 1, f_ch_info},
|
||||||
{"ch_log", 1, 2, f_ch_log},
|
{"ch_log", 1, 2, f_ch_log},
|
||||||
{"ch_logfile", 1, 2, f_ch_logfile},
|
{"ch_logfile", 1, 2, f_ch_logfile},
|
||||||
{"ch_open", 1, 2, f_ch_open},
|
{"ch_open", 1, 2, f_ch_open},
|
||||||
@@ -10028,6 +10030,18 @@ f_ch_getjob(typval_T *argvars, typval_T *rettv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "ch_info()" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_ch_info(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
channel_T *channel = get_channel_arg(&argvars[0], TRUE);
|
||||||
|
|
||||||
|
if (channel != NULL && rettv_dict_alloc(rettv) != FAIL)
|
||||||
|
channel_info(channel, rettv->vval.v_dict);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "ch_log()" function
|
* "ch_log()" function
|
||||||
*/
|
*/
|
||||||
|
@@ -20,6 +20,7 @@ int channel_collapse(channel_T *channel, int part);
|
|||||||
int channel_can_write_to(channel_T *channel);
|
int channel_can_write_to(channel_T *channel);
|
||||||
int channel_is_open(channel_T *channel);
|
int channel_is_open(channel_T *channel);
|
||||||
char *channel_status(channel_T *channel);
|
char *channel_status(channel_T *channel);
|
||||||
|
void channel_info(channel_T *channel, dict_T *dict);
|
||||||
void channel_close(channel_T *channel, int invoke_close_cb);
|
void channel_close(channel_T *channel, int invoke_close_cb);
|
||||||
char_u *channel_peek(channel_T *channel, int part);
|
char_u *channel_peek(channel_T *channel, int part);
|
||||||
void channel_clear(channel_T *channel);
|
void channel_clear(channel_T *channel);
|
||||||
|
@@ -120,9 +120,16 @@ func s:communicate(port)
|
|||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
if has('job')
|
if has('job')
|
||||||
" check that no job is handled correctly
|
" check that getjob without a job is handled correctly
|
||||||
call assert_equal('no process', string(ch_getjob(handle)))
|
call assert_equal('no process', string(ch_getjob(handle)))
|
||||||
endif
|
endif
|
||||||
|
let dict = ch_info(handle)
|
||||||
|
call assert_true(dict.id != 0)
|
||||||
|
call assert_equal('open', dict.status)
|
||||||
|
call assert_equal(a:port, string(dict.port))
|
||||||
|
call assert_equal('open', dict.sock_status)
|
||||||
|
call assert_equal('socket', dict.sock_io)
|
||||||
|
|
||||||
" Simple string request and reply.
|
" Simple string request and reply.
|
||||||
call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
|
call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
|
||||||
|
|
||||||
|
@@ -748,6 +748,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 */
|
||||||
|
/**/
|
||||||
|
1624,
|
||||||
/**/
|
/**/
|
||||||
1623,
|
1623,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user