changeset 7895:bff95e0d8885 v7.4.1244

commit https://github.com/vim/vim/commit/f57969a20a4398f56e3028a6cc1102f9f9286ccf Author: Bram Moolenaar <Bram@vim.org> Date: Tue Feb 2 20:47:49 2016 +0100 patch 7.4.1244 Problem: The channel functions don't sort together. Solution: Use a common "ch_" prefix.
author Christian Brabandt <cb@256bit.org>
date Tue, 02 Feb 2016 21:00:07 +0100
parents ef15b397fcc1
children 16e8b23d8fd8
files runtime/doc/eval.txt runtime/tools/demoserver.py src/eval.c src/version.c
diffstat 4 files changed, 258 insertions(+), 259 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -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
@@ -1810,6 +1810,13 @@ byteidxcomp( {expr}, {nr})	Number	byte i
 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}
@@ -1820,8 +1827,6 @@ complete_add( {expr})		Number	add comple
 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}
@@ -2029,10 +2034,6 @@ searchpairpos( {start}, {middle}, {end} 
 				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
@@ -2666,7 +2667,10 @@ confirm({msg} [, {choices} [, {default} 
 		don't fit, a vertical layout is used anyway.  For some systems
 		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|.
 		Returns the channel handle on success.  Returns a negative
 		number for failure.
@@ -2680,6 +2684,23 @@ connect({address}, {mode} [, {callback}]
 		{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.
@@ -5615,23 +5636,6 @@ searchpos({pattern} [, {flags} [, {stopl
 <		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>").
--- a/runtime/tools/demoserver.py
+++ b/runtime/tools/demoserver.py
@@ -1,15 +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 = connect('localhost:8765', 'json')
+#  :let handle = ch_open('localhost:8765', 'json')
 #
 # 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.:
 #   ["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
--- a/src/eval.c
+++ b/src/eval.c
@@ -499,6 +499,12 @@ static void f_call(typval_T *argvars, ty
 #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,9 +521,6 @@ static void f_copy(typval_T *argvars, ty
 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);
@@ -526,9 +529,6 @@ static void f_delete(typval_T *argvars, 
 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);
@@ -703,10 +703,6 @@ static void f_searchdecl(typval_T *argva
 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);
@@ -8003,6 +7999,12 @@ static struct fst
 #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,9 +8016,6 @@ static struct fst
     {"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},
@@ -8030,9 +8029,6 @@ static struct fst
     {"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},
@@ -8211,10 +8207,6 @@ static struct fst
     {"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},
@@ -9685,6 +9677,213 @@ f_ceil(typval_T *argvars, typval_T *rett
 }
 #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,84 +10232,6 @@ f_count(typval_T *argvars, typval_T *ret
     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
  *
@@ -10349,44 +10470,6 @@ f_diff_hlID(typval_T *argvars UNUSED, ty
 #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
  */
@@ -16860,102 +16943,6 @@ f_searchpos(typval_T *argvars, typval_T 
 	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)
 {
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1244,
+/**/
     1243,
 /**/
     1242,