Patch 7.4.1244
Problem: The channel functions don't sort together.
Solution: Use a common "ch_" prefix.
Files: src/eval.c, runtime/doc/eval.txt, runtime/tools/demoserver.py
*** ../vim-7.4.1243/src/eval.c 2016-02-02 18:19:52.794743928 +0100
--- src/eval.c 2016-02-02 20:08:47.570922261 +0100
***************
*** 499,504 ****
--- 499,510 ----
#ifdef FEAT_FLOAT
static void f_ceil(typval_T *argvars, typval_T *rettv);
#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_char2nr(typval_T *argvars, typval_T *rettv);
static void f_cindent(typval_T *argvars, typval_T *rettv);
***************
*** 515,523 ****
static void f_cos(typval_T *argvars, typval_T *rettv);
static void f_cosh(typval_T *argvars, typval_T *rettv);
#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_cscope_connection(typval_T *argvars, typval_T *rettv);
static void f_cursor(typval_T *argsvars, typval_T *rettv);
--- 521,526 ----
***************
*** 526,534 ****
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_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_escape(typval_T *argvars, typval_T *rettv);
static void f_eval(typval_T *argvars, typval_T *rettv);
--- 529,534 ----
***************
*** 703,712 ****
static void f_searchpair(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);
- #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_serverlist(typval_T *argvars, typval_T *rettv);
static void f_setbufvar(typval_T *argvars, typval_T *rettv);
--- 703,708 ----
***************
*** 8003,8008 ****
--- 7999,8010 ----
#ifdef FEAT_FLOAT
{"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
{"changenr", 0, 0, f_changenr},
{"char2nr", 1, 2, f_char2nr},
{"cindent", 1, 1, f_cindent},
***************
*** 8014,8022 ****
{"complete_check", 0, 0, f_complete_check},
#endif
{"confirm", 1, 4, f_confirm},
- #ifdef FEAT_CHANNEL
- {"connect", 2, 3, f_connect},
- #endif
{"copy", 1, 1, f_copy},
#ifdef FEAT_FLOAT
{"cos", 1, 1, f_cos},
--- 8016,8021 ----
***************
*** 8030,8038 ****
{"did_filetype", 0, 0, f_did_filetype},
{"diff_filler", 1, 1, f_diff_filler},
{"diff_hlID", 2, 2, f_diff_hlID},
- #ifdef FEAT_CHANNEL
- {"disconnect", 1, 1, f_disconnect},
- #endif
{"empty", 1, 1, f_empty},
{"escape", 2, 2, f_escape},
{"eval", 1, 1, f_eval},
--- 8029,8034 ----
***************
*** 8211,8220 ****
{"searchpair", 3, 7, f_searchpair},
{"searchpairpos", 3, 7, f_searchpairpos},
{"searchpos", 1, 4, f_searchpos},
- #ifdef FEAT_CHANNEL
- {"sendexpr", 2, 3, f_sendexpr},
- {"sendraw", 2, 3, f_sendraw},
- #endif
{"server2client", 2, 2, f_server2client},
{"serverlist", 0, 0, f_serverlist},
{"setbufvar", 3, 3, f_setbufvar},
--- 8207,8212 ----
***************
*** 9685,9690 ****
--- 9677,9889 ----
}
#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
*/
***************
*** 10033,10116 ****
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
*
--- 10232,10237 ----
***************
*** 10349,10392 ****
#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
*/
--- 10470,10475 ----
***************
*** 16860,16961 ****
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
f_server2client(typval_T *argvars UNUSED, typval_T *rettv)
{
--- 16943,16948 ----
*** ../vim-7.4.1243/runtime/doc/eval.txt 2016-01-28 22:36:15.056065002
+0100
--- runtime/doc/eval.txt 2016-02-02 19:59:46.840542732 +0100
***************
*** 1785,1790 ****
--- 1810,1822 ----
call( {func}, {arglist} [, {dict}])
any call {func} with arguments {arglist}
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
char2nr( {expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
cindent( {lnum}) Number C indent for line {lnum}
***************
*** 1795,1802 ****
complete_check() Number check for key typed during completion
confirm( {msg} [, {choices} [, {default} [, {type}]]])
Number number of choice picked by user
- connect( {address}, {mode} [, {callback}])
- Number open a channel
copy( {expr}) any make a shallow copy of {expr}
cos( {expr}) Float cosine of {expr}
cosh( {expr}) Float hyperbolic cosine of {expr}
--- 1827,1832 ----
***************
*** 2004,2013 ****
List search for other end of start/end pair
searchpos( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
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})
Number send reply string
serverlist() String get a list of available servers
--- 2034,2039 ----
***************
*** 2637,2644 ****
don't fit, a vertical layout is used anyway. For some systems
the horizontal layout is always used.
! connect({address}, {mode} [, {callback}]) *connect()*
Open a channel to {address}. See |channel|.
{address} has the form "hostname:port", e.g.,
"localhost:8765".
--- 2667,2679 ----
don't fit, a vertical layout is used anyway. For some systems
the horizontal layout is always used.
! ch_close({handle}) *ch_close()*
! Close channel {handle}. See |channel|.
!
! ch_open({address}, {mode} [, {callback}]) *ch_open()*
Open a channel to {address}. See |channel|.
+ Returns the channel handle on success. Returns a negative
+ number for failure.
{address} has the form "hostname:port", e.g.,
"localhost:8765".
***************
*** 2649,2654 ****
--- 2684,2706 ----
{callback} is a function that handles received messages on the
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({expr}) Make a copy of {expr}. For Numbers and Strings this isn't
different from using {expr} directly.
***************
*** 5552,5574 ****
< In this example "submatch" is 2 when a lowercase letter is
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()*
Send a reply string to {clientid}. The most recent {clientid}
that sent a string can be retrieved with expand("<client>").
--- 5636,5641 ----
*** ../vim-7.4.1243/runtime/tools/demoserver.py 2016-02-01 22:01:06.044672631
+0100
--- runtime/tools/demoserver.py 2016-02-02 20:01:33.583433236 +0100
***************
*** 1,15 ****
#!/usr/bin/python
# Server that will accept connections from a Vim channel.
# Run this server and then in Vim you can open the channel:
! # :let handle = connect('localhost:8765', 'json')
#
# Then Vim can send requests to the server:
! # :let response = sendexpr(handle, 'hello!')
#
# And you can control Vim by typing a JSON message here, e.g.:
# ["ex","echo 'hi there'"]
#
# See ":help channel-demo" in Vim.
from __future__ import print_function
import json
--- 1,21 ----
#!/usr/bin/python
+ #
# Server that will accept connections from a Vim channel.
# Run this server and then in Vim you can open the channel:
! # :let handle = ch_open('localhost:8765', 'json')
#
# Then Vim can send requests to the server:
! # :let response = ch_sendexpr(handle, 'hello!')
#
# And you can control Vim by typing a JSON message here, e.g.:
# ["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.
+ #
+ # This requires Python 2.6 or later.
from __future__ import print_function
import json
*** ../vim-7.4.1243/src/version.c 2016-02-02 19:43:53.046456217 +0100
--- src/version.c 2016-02-02 19:45:39.481349993 +0100
***************
*** 744,745 ****
--- 744,747 ----
{ /* Add new patch number below this line */
+ /**/
+ 1244,
/**/
--
hundred-and-one symptoms of being an internet addict:
114. You are counting items, you go "0,1,2,3,4,5,6,7,8,9,A,B,C,D...".
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.