Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2016-02-13 22:11:24 -08:00
18 changed files with 753 additions and 595 deletions
+2 -2
View File
@@ -156,8 +156,8 @@ extern NSTimeInterval MMBalloonEvalInternalDelay;
- (BOOL)imState;
- (void)setImState:(BOOL)activated;
- (void)addChannel:(int)idx fileDescriptor:(int)fd;
- (void)removeChannel:(int)idx;
- (void)addChannel:(channel_T *)channel;
- (void)removeChannel:(channel_T *)channel;
#ifdef FEAT_BEVAL
- (void)setLastToolTip:(NSString *)toolTip;
+12 -16
View File
@@ -168,7 +168,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
CFRunLoopSourceRef runLoopSource;
}
- (id)initWithIndex:(int)idx fileDescriptor:(int)fd;
- (id)initWithChannel:(channel_T *)channel;
@end
@@ -1684,20 +1684,17 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
[self flushQueue:YES];
}
- (void)addChannel:(int)idx fileDescriptor:(int)fd
- (void)addChannel:(channel_T *)channel
{
if (fd == -1)
return;
NSNumber *key = [NSNumber numberWithInt:idx];
MMChannel *channel =
[[[MMChannel alloc] initWithIndex:idx fileDescriptor:fd] autorelease];
[channelDict setObject:channel forKey:key];
NSValue *key = [NSValue valueWithPointer:channel];
MMChannel *mmChannel =
[[[MMChannel alloc] initWithChannel:channel] autorelease];
[channelDict setObject:mmChannel forKey:key];
}
- (void)removeChannel:(int)idx
- (void)removeChannel:(channel_T *)channel
{
NSNumber *key = [NSNumber numberWithInt:idx];
NSValue *key = [NSValue valueWithPointer:channel];
[channelDict removeObjectForKey:key];
}
@@ -3432,20 +3429,19 @@ static void socketReadCallback(CFSocketRef s,
void *info)
{
#ifdef FEAT_CHANNEL
int idx = (int)(intptr_t)info;
channel_read(idx, FALSE, "socketReadCallback");
channel_read((channel_T *)info, FALSE, "socketReadCallback");
#endif
}
- (id)initWithIndex:(int)idx fileDescriptor:(int)fd
- (id)initWithChannel:(channel_T *)channel
{
self = [super init];
if (!self) return nil;
// Tell CFRunLoop that we are interested in channel socket input.
CFSocketContext ctx = {0, (void *)(intptr_t)idx, NULL, NULL, NULL};
CFSocketContext ctx = {0, channel, NULL, NULL, NULL};
socket = CFSocketCreateWithNative(kCFAllocatorDefault,
fd,
channel->ch_sock,
kCFSocketReadCallBack,
&socketReadCallback,
&ctx);
+4 -4
View File
@@ -2242,15 +2242,15 @@ static int vimModMaskToEventModifierFlags(int mods)
// -- Channel Support ------------------------------------------------------
void
gui_macvim_add_channel(int idx, int fd)
gui_macvim_add_channel(channel_T *channel)
{
[[MMBackend sharedInstance] addChannel:idx fileDescriptor:fd];
[[MMBackend sharedInstance] addChannel:channel];
}
void
gui_macvim_remove_channel(int idx)
gui_macvim_remove_channel(channel_T *channel)
{
[[MMBackend sharedInstance] removeChannel:idx];
[[MMBackend sharedInstance] removeChannel:channel];
}
+459 -425
View File
File diff suppressed because it is too large Load Diff
+160 -66
View File
@@ -509,6 +509,7 @@ static void f_ch_open(typval_T *argvars, typval_T *rettv);
static void f_ch_readraw(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);
static void f_ch_status(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);
@@ -626,7 +627,9 @@ static void f_isdirectory(typval_T *argvars, typval_T *rettv);
static void f_islocked(typval_T *argvars, typval_T *rettv);
static void f_items(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_JOB
# ifdef FEAT_CHANNEL
static void f_job_getchannel(typval_T *argvars, typval_T *rettv);
# endif
static void f_job_start(typval_T *argvars, typval_T *rettv);
static void f_job_stop(typval_T *argvars, typval_T *rettv);
static void f_job_status(typval_T *argvars, typval_T *rettv);
@@ -3084,6 +3087,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
case VAR_FUNC:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
break;
case VAR_LIST:
@@ -3863,6 +3867,7 @@ item_lock(typval_T *tv, int deep, int lock)
case VAR_FLOAT:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
break;
case VAR_LIST:
@@ -5359,6 +5364,7 @@ eval_index(
#endif
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
if (verbose)
EMSG(_("E909: Cannot index a special variable"));
return FAIL;
@@ -5471,6 +5477,7 @@ eval_index(
case VAR_FLOAT:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
break; /* not evaluating, skipping over subscript */
case VAR_NUMBER:
@@ -6223,6 +6230,10 @@ tv_equal(
case VAR_JOB:
#ifdef FEAT_JOB
return tv1->vval.v_job == tv2->vval.v_job;
#endif
case VAR_CHANNEL:
#ifdef FEAT_CHANNEL
return tv1->vval.v_channel == tv2->vval.v_channel;
#endif
case VAR_UNKNOWN:
break;
@@ -7719,12 +7730,28 @@ failret:
return OK;
}
#ifdef FEAT_CHANNEL
static void
channel_unref(channel_T *channel)
{
if (channel != NULL && --channel->ch_refcount <= 0)
channel_free(channel);
}
#endif
#ifdef FEAT_JOB
static void
job_free(job_T *job)
{
if (job->jv_channel >= 0)
channel_close(job->jv_channel);
# ifdef FEAT_CHANNEL
if (job->jv_channel != NULL)
{
/* The channel doesn't count as a references for the job, we need to
* NULL the reference when the job is freed. */
job->jv_channel->ch_job = NULL;
channel_unref(job->jv_channel);
}
# endif
mch_clear_job(job);
vim_free(job);
}
@@ -7746,9 +7773,7 @@ job_alloc(void)
job = (job_T *)alloc_clear(sizeof(job_T));
if (job != NULL)
{
job->jv_refcount = 1;
}
return job;
}
@@ -7850,6 +7875,7 @@ echo_string(
case VAR_NUMBER:
case VAR_UNKNOWN:
case VAR_JOB:
case VAR_CHANNEL:
*tofree = NULL;
r = get_tv_string_buf(tv, numbuf);
break;
@@ -7906,6 +7932,7 @@ tv2string(
case VAR_DICT:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
case VAR_UNKNOWN:
break;
}
@@ -8093,6 +8120,7 @@ static struct fst
{"ch_readraw", 1, 2, f_ch_readraw},
{"ch_sendexpr", 2, 3, f_ch_sendexpr},
{"ch_sendraw", 2, 3, f_ch_sendraw},
{"ch_status", 1, 1, f_ch_status},
#endif
{"changenr", 0, 0, f_changenr},
{"char2nr", 1, 2, f_char2nr},
@@ -8214,7 +8242,9 @@ static struct fst
{"islocked", 1, 1, f_islocked},
{"items", 1, 1, f_items},
#ifdef FEAT_JOB
# ifdef FEAT_CHANNEL
{"job_getchannel", 1, 1, f_job_getchannel},
# endif
{"job_start", 1, 2, f_job_start},
{"job_status", 1, 1, f_job_status},
{"job_stop", 1, 2, f_job_stop},
@@ -9781,27 +9811,27 @@ f_ceil(typval_T *argvars, typval_T *rettv)
#ifdef FEAT_CHANNEL
/*
* Get the channel index from the handle argument.
* Returns -1 if the handle is invalid or the channel is closed.
* Get the channel from the argument.
* Returns NULL if the handle is invalid.
*/
static int
static channel_T *
get_channel_arg(typval_T *tv)
{
int ch_idx;
channel_T *channel;
if (tv->v_type != VAR_NUMBER)
if (tv->v_type != VAR_CHANNEL)
{
EMSG2(_(e_invarg2), get_tv_string(tv));
return -1;
return NULL;
}
ch_idx = tv->vval.v_number;
channel = tv->vval.v_channel;
if (!channel_can_write_to(ch_idx))
if (channel == NULL || !channel_is_open(channel))
{
EMSGN(_("E906: not an open channel"), ch_idx);
return -1;
EMSG(_("E906: not an open channel"));
return NULL;
}
return ch_idx;
return channel;
}
/*
@@ -9810,10 +9840,10 @@ get_channel_arg(typval_T *tv)
static void
f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
{
int ch_idx = get_channel_arg(&argvars[0]);
channel_T *channel = get_channel_arg(&argvars[0]);
if (ch_idx >= 0)
channel_close(ch_idx);
if (channel != NULL)
channel_close(channel);
}
/*
@@ -9873,10 +9903,11 @@ f_ch_open(typval_T *argvars, typval_T *rettv)
int waittime = 0;
int timeout = 2000;
ch_mode_T ch_mode = MODE_JSON;
int ch_idx;
channel_T *channel;
/* default: fail */
rettv->vval.v_number = -1;
rettv->v_type = VAR_CHANNEL;
rettv->vval.v_channel = NULL;
address = get_tv_string(&argvars[0]);
if (argvars[1].v_type != VAR_UNKNOWN
@@ -9936,15 +9967,15 @@ f_ch_open(typval_T *argvars, typval_T *rettv)
return;
}
ch_idx = channel_open((char *)address, port, waittime, NULL);
if (ch_idx >= 0)
channel = channel_open((char *)address, port, waittime, NULL);
if (channel != NULL)
{
channel_set_json_mode(ch_idx, ch_mode);
channel_set_timeout(ch_idx, timeout);
channel_set_json_mode(channel, ch_mode);
channel_set_timeout(channel, timeout);
if (callback != NULL && *callback != NUL)
channel_set_callback(ch_idx, callback);
channel_set_callback(channel, callback);
}
rettv->vval.v_number = ch_idx;
rettv->vval.v_channel = channel;
}
/*
@@ -9953,53 +9984,65 @@ f_ch_open(typval_T *argvars, typval_T *rettv)
static void
f_ch_readraw(typval_T *argvars, typval_T *rettv)
{
int ch_idx;
channel_T *channel;
/* return an empty string by default */
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
ch_idx = get_channel_arg(&argvars[0]);
if (ch_idx < 0)
channel = get_channel_arg(&argvars[0]);
if (channel != NULL)
rettv->vval.v_string = channel_read_block(channel);
}
/*
* "ch_status()" function
*/
static void
f_ch_status(typval_T *argvars, typval_T *rettv)
{
/* return an empty string by default */
rettv->v_type = VAR_STRING;
if (argvars[0].v_type != VAR_CHANNEL)
{
EMSG(_(e_invarg));
return;
EMSG2(_(e_invarg2), get_tv_string(&argvars[0]));
rettv->vval.v_string = NULL;
}
rettv->vval.v_string = channel_read_block(ch_idx);
else
rettv->vval.v_string = vim_strsave(
(char_u *)channel_status(argvars[0].vval.v_channel));
}
/*
* common for "sendexpr()" and "sendraw()"
* Returns the channel index if the caller should read the response.
* Otherwise returns -1.
* Returns the channel if the caller should read the response.
* Otherwise returns NULL.
*/
static int
static channel_T *
send_common(typval_T *argvars, char_u *text, int id, char *fun)
{
int ch_idx;
channel_T *channel;
char_u *callback = NULL;
ch_idx = get_channel_arg(&argvars[0]);
if (ch_idx < 0)
{
EMSG(_(e_invarg));
return -1;
}
channel = get_channel_arg(&argvars[0]);
if (channel == NULL)
return NULL;
if (argvars[2].v_type != VAR_UNKNOWN)
{
callback = get_callback(&argvars[2]);
if (callback == NULL)
return -1;
return NULL;
}
/* Set the callback. An empty callback means no callback and not reading
* the response. */
if (callback != NULL && *callback != NUL)
channel_set_req_callback(ch_idx, callback, id);
channel_set_req_callback(channel, callback, id);
if (channel_send(ch_idx, text, fun) == OK && callback == NULL)
return ch_idx;
return -1;
if (channel_send(channel, text, fun) == OK && callback == NULL)
return channel;
return NULL;
}
/*
@@ -10010,7 +10053,7 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
{
char_u *text;
typval_T *listtv;
int ch_idx;
channel_T *channel;
int id;
ch_mode_T ch_mode;
@@ -10018,14 +10061,11 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
ch_idx = get_channel_arg(&argvars[0]);
if (ch_idx < 0)
{
EMSG(_(e_invarg));
channel = get_channel_arg(&argvars[0]);
if (channel == NULL)
return;
}
ch_mode = channel_get_mode(ch_idx);
ch_mode = channel_get_mode(channel);
if (ch_mode == MODE_RAW)
{
EMSG(_("E912: cannot use ch_sendexpr() with a raw channel"));
@@ -10038,11 +10078,11 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
if (text == NULL)
return;
ch_idx = send_common(argvars, text, id, "sendexpr");
channel = send_common(argvars, text, id, "sendexpr");
vim_free(text);
if (ch_idx >= 0)
if (channel != NULL)
{
if (channel_read_json_block(ch_idx, id, &listtv) == OK)
if (channel_read_json_block(channel, id, &listtv) == OK)
{
list_T *list = listtv->vval.v_list;
@@ -10050,7 +10090,7 @@ f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
* avoid the value being freed. */
*rettv = list->lv_last->li_tv;
list->lv_last->li_tv.v_type = VAR_NUMBER;
clear_tv(listtv);
free_tv(listtv);
}
}
}
@@ -10063,16 +10103,16 @@ f_ch_sendraw(typval_T *argvars, typval_T *rettv)
{
char_u buf[NUMBUFLEN];
char_u *text;
int ch_idx;
channel_T *channel;
/* 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, 0, "sendraw");
if (ch_idx >= 0)
rettv->vval.v_string = channel_read_block(ch_idx);
channel = send_common(argvars, text, 0, "sendraw");
if (channel != NULL)
rettv->vval.v_string = channel_read_block(channel);
}
#endif
@@ -10708,7 +10748,14 @@ f_empty(typval_T *argvars, typval_T *rettv)
case VAR_JOB:
#ifdef FEAT_JOB
n = argvars[0].vval.v_job->jv_status != JOB_STARTED;
n = argvars[0].vval.v_job == NULL
|| argvars[0].vval.v_job->jv_status != JOB_STARTED;
break;
#endif
case VAR_CHANNEL:
#ifdef FEAT_CHANNEL
n = argvars[0].vval.v_channel == NULL
|| !channel_is_open(argvars[0].vval.v_channel);
break;
#endif
case VAR_UNKNOWN:
@@ -14373,6 +14420,8 @@ f_items(typval_T *argvars, typval_T *rettv)
}
#ifdef FEAT_JOB
# ifdef FEAT_CHANNEL
/*
* "job_getchannel()" function
*/
@@ -14385,10 +14434,13 @@ f_job_getchannel(typval_T *argvars, typval_T *rettv)
{
job_T *job = argvars[0].vval.v_job;
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = job->jv_channel;
rettv->v_type = VAR_CHANNEL;
rettv->vval.v_channel = job->jv_channel;
if (job->jv_channel != NULL)
++job->jv_channel->ch_refcount;
}
}
# endif
/*
* "job_start()" function
@@ -14678,6 +14730,7 @@ f_len(typval_T *argvars, typval_T *rettv)
case VAR_FLOAT:
case VAR_FUNC:
case VAR_JOB:
case VAR_CHANNEL:
EMSG(_("E701: Invalid type for len()"));
break;
}
@@ -20067,7 +20120,8 @@ f_type(typval_T *argvars, typval_T *rettv)
else
n = 7;
break;
case VAR_JOB: n = 8; break;
case VAR_JOB: n = 8; break;
case VAR_CHANNEL: n = 9; break;
case VAR_UNKNOWN:
EMSG2(_(e_intern2), "f_type(UNKNOWN)");
n = -1;
@@ -21438,6 +21492,11 @@ free_tv(typval_T *varp)
#ifdef FEAT_JOB
job_unref(varp->vval.v_job);
break;
#endif
case VAR_CHANNEL:
#ifdef FEAT_CHANNEL
channel_unref(varp->vval.v_channel);
break;
#endif
case VAR_NUMBER:
case VAR_FLOAT:
@@ -21489,6 +21548,11 @@ clear_tv(typval_T *varp)
varp->vval.v_job = NULL;
#endif
break;
case VAR_CHANNEL:
#ifdef FEAT_CHANNEL
channel_unref(varp->vval.v_channel);
varp->vval.v_channel = NULL;
#endif
case VAR_UNKNOWN:
break;
}
@@ -21557,6 +21621,11 @@ get_tv_number_chk(typval_T *varp, int *denote)
#ifdef FEAT_JOB
EMSG(_("E910: Using a Job as a Number"));
break;
#endif
case VAR_CHANNEL:
#ifdef FEAT_CHANNEL
EMSG(_("E913: Using a Channel as a Number"));
break;
#endif
case VAR_UNKNOWN:
EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
@@ -21598,6 +21667,11 @@ get_tv_float(typval_T *varp)
# ifdef FEAT_JOB
EMSG(_("E911: Using a Job as a Float"));
break;
# endif
case VAR_CHANNEL:
# ifdef FEAT_CHANNEL
EMSG(_("E914: Using a Channel as a Float"));
break;
# endif
case VAR_UNKNOWN:
EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)");
@@ -21732,6 +21806,18 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf)
# endif
return buf;
}
#endif
break;
case VAR_CHANNEL:
#ifdef FEAT_CHANNEL
{
channel_T *channel = varp->vval.v_channel;
char *status = channel_status(channel);
vim_snprintf((char *)buf, NUMBUFLEN,
"channel %d %s", channel->ch_id, status);
return buf;
}
#endif
break;
case VAR_UNKNOWN:
@@ -22363,6 +22449,12 @@ copy_tv(typval_T *from, typval_T *to)
to->vval.v_job = from->vval.v_job;
++to->vval.v_job->jv_refcount;
break;
#endif
case VAR_CHANNEL:
#ifdef FEAT_CHANNEL
to->vval.v_channel = from->vval.v_channel;
++to->vval.v_channel->ch_refcount;
break;
#endif
case VAR_STRING:
case VAR_FUNC:
@@ -22431,6 +22523,7 @@ item_copy(
case VAR_FUNC:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
copy_tv(from, to);
break;
case VAR_LIST:
@@ -25103,6 +25196,7 @@ write_viminfo_varlist(FILE *fp)
case VAR_UNKNOWN:
case VAR_FUNC:
case VAR_JOB:
case VAR_CHANNEL:
continue;
}
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
+3 -3
View File
@@ -1780,14 +1780,14 @@ process_message(void)
#ifdef FEAT_CHANNEL
if (msg.message == WM_NETBEANS)
{
int channel_idx = channel_fd2idx((sock_T)msg.wParam);
channel_T *channel = channel_fd2channel((sock_T)msg.wParam);
if (channel_idx >= 0)
if (channel != NULL)
{
/* Disable error messages, they can mess up the display and throw
* an exception. */
++emsg_off;
channel_read(channel_idx, FALSE, "process_message");
channel_read(channel, FALSE, "process_message");
--emsg_off;
}
return;
+1
View File
@@ -1565,6 +1565,7 @@ do_pyeval (char_u *str, typval_T *rettv)
case VAR_FLOAT:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
break;
}
}
+1
View File
@@ -1654,6 +1654,7 @@ do_py3eval (char_u *str, typval_T *rettv)
case VAR_FLOAT:
case VAR_SPECIAL:
case VAR_JOB:
case VAR_CHANNEL:
break;
}
}
+1
View File
@@ -183,6 +183,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_FUNC:
case VAR_JOB:
case VAR_CHANNEL:
/* no JSON equivalent TODO: better error */
EMSG(_(e_invarg));
return FAIL;
+3
View File
@@ -1138,6 +1138,9 @@ free_all_mem(void)
# endif
# ifdef FEAT_DIFF
diff_clear(curtab);
# endif
# ifdef FEAT_CHANNEL
channel_free_all();
# endif
clear_sb_text(); /* free any scrollback text */
+17 -17
View File
@@ -63,8 +63,8 @@ static int nb_do_cmd(int, char_u *, int, int, char_u *);
static void nb_send(char *buf, char *fun);
static void nb_free(void);
#define NETBEANS_OPEN (nb_channel_idx >= 0 && channel_is_open(nb_channel_idx))
static int nb_channel_idx = -1;
#define NETBEANS_OPEN (channel_can_write_to(nb_channel))
static channel_T *nb_channel = NULL;
static int r_cmdno; /* current command number for reply */
static int dosetvisible = FALSE;
@@ -85,7 +85,7 @@ static int inAtomic = 0;
static void
nb_channel_closed(void)
{
nb_channel_idx = -1;
nb_channel = NULL;
}
/*
@@ -98,10 +98,10 @@ netbeans_close(void)
if (NETBEANS_OPEN)
{
netbeans_send_disconnect();
if (nb_channel_idx >= 0)
if (nb_channel != NULL)
/* Close the socket and remove the input handlers. */
channel_close(nb_channel_idx);
nb_channel_idx = -1;
channel_close(nb_channel);
nb_channel = NULL;
}
#ifdef FEAT_BEVAL
@@ -213,8 +213,8 @@ netbeans_connect(char *params, int doabort)
if (hostname != NULL && address != NULL && password != NULL)
{
port = atoi(address);
nb_channel_idx = channel_open(hostname, port, 0, nb_channel_closed);
if (nb_channel_idx >= 0)
nb_channel = channel_open(hostname, port, 0, nb_channel_closed);
if (nb_channel != NULL)
{
/* success */
# ifdef FEAT_BEVAL
@@ -230,7 +230,7 @@ netbeans_connect(char *params, int doabort)
}
}
if (nb_channel_idx < 0 && doabort)
if (nb_channel == NULL && doabort)
getout(1);
vim_free(hostname);
@@ -383,9 +383,9 @@ netbeans_parse_messages(void)
char_u *p;
int own_node;
while (nb_channel_idx >= 0)
while (nb_channel != NULL)
{
buffer = channel_peek(nb_channel_idx);
buffer = channel_peek(nb_channel);
if (buffer == NULL)
break; /* nothing to read */
@@ -396,7 +396,7 @@ netbeans_parse_messages(void)
/* Command isn't complete. If there is no following buffer,
* return (wait for more). If there is another buffer following,
* prepend the text to that buffer and delete this one. */
if (channel_collapse(nb_channel_idx) == FAIL)
if (channel_collapse(nb_channel) == FAIL)
return;
}
else
@@ -409,7 +409,7 @@ netbeans_parse_messages(void)
if (*p == NUL)
{
own_node = TRUE;
channel_get(nb_channel_idx);
channel_get(nb_channel);
}
else
own_node = FALSE;
@@ -600,8 +600,8 @@ nb_free(void)
}
/* free the queued netbeans commands */
if (nb_channel_idx >= 0)
channel_clear(nb_channel_idx);
if (nb_channel != NULL)
channel_clear(nb_channel);
}
/*
@@ -756,8 +756,8 @@ netbeans_end(void)
static void
nb_send(char *buf, char *fun)
{
if (nb_channel_idx >= 0)
channel_send(nb_channel_idx, (char_u *)buf, fun);
if (nb_channel != NULL)
channel_send(nb_channel, (char_u *)buf, fun);
}
/*
+6 -6
View File
@@ -5065,7 +5065,7 @@ mch_start_job(char **argv, job_T *job)
int fd_in[2]; /* for stdin */
int fd_out[2]; /* for stdout */
int fd_err[2]; /* for stderr */
int ch_idx;
channel_T *channel;
/* default is to fail */
job->jv_status = JOB_FAILED;
@@ -5077,8 +5077,8 @@ mch_start_job(char **argv, job_T *job)
if ((pipe(fd_in) < 0) || (pipe(fd_out) < 0) ||(pipe(fd_err) < 0))
goto failed;
ch_idx = add_channel();
if (ch_idx < 0)
channel = add_channel();
if (channel == NULL)
goto failed;
pid = fork(); /* maybe we should use vfork() */
@@ -5130,14 +5130,14 @@ mch_start_job(char **argv, job_T *job)
/* parent */
job->jv_pid = pid;
job->jv_status = JOB_STARTED;
job->jv_channel = ch_idx;
job->jv_channel = channel;
/* child stdin, stdout and stderr */
close(fd_in[0]);
close(fd_out[1]);
close(fd_err[1]);
channel_set_pipes(ch_idx, fd_in[1], fd_out[0], fd_err[0]);
channel_set_job(ch_idx, job);
channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
channel_set_job(channel, job);
return;
+25 -22
View File
@@ -1,33 +1,36 @@
/* channel.c */
void ch_logfile(FILE *file);
int add_channel(void);
channel_T *add_channel(void);
void channel_free(channel_T *channel);
void channel_gui_register_all(void);
int channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void));
void channel_set_pipes(int idx, int in, int out, int err);
void channel_set_job(int idx, job_T *job);
void channel_set_json_mode(int idx, ch_mode_T ch_mode);
void channel_set_timeout(int idx, int timeout);
void channel_set_callback(int idx, char_u *callback);
void channel_set_req_callback(int idx, char_u *callback, int id);
char_u *channel_get(int idx);
int channel_collapse(int idx);
int channel_can_write_to(int idx);
int channel_is_open(int idx);
void channel_close(int idx);
int channel_save(int idx, char_u *buf, int len);
char_u *channel_peek(int idx);
void channel_clear(int idx);
channel_T *channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void));
void channel_set_pipes(channel_T *channel, int in, int out, int err);
void channel_set_job(channel_T *channel, job_T *job);
void channel_set_json_mode(channel_T *channel, ch_mode_T ch_mode);
void channel_set_timeout(channel_T *channel, int timeout);
void channel_set_callback(channel_T *channel, char_u *callback);
void channel_set_req_callback(channel_T *channel, char_u *callback, int id);
char_u *channel_get(channel_T *channel);
int channel_collapse(channel_T *channel);
int channel_can_write_to(channel_T *channel);
int channel_is_open(channel_T *channel);
char *channel_status(channel_T *channel);
void channel_close(channel_T *channel);
int channel_save(channel_T *channel, char_u *buf, int len);
char_u *channel_peek(channel_T *channel);
void channel_clear(channel_T *channel);
void channel_free_all(void);
int channel_get_id(void);
void channel_read(int idx, int use_stderr, char *func);
char_u *channel_read_block(int idx);
int channel_read_json_block(int ch_idx, int id, typval_T **rettv);
int channel_fd2idx(sock_T fd);
int channel_send(int idx, char_u *buf, char *fun);
void channel_read(channel_T *channel, int use_stderr, char *func);
char_u *channel_read_block(channel_T *channel);
int channel_read_json_block(channel_T *channel, int id, typval_T **rettv);
channel_T *channel_fd2channel(sock_T fd);
int channel_send(channel_T *channel, char_u *buf, char *fun);
int channel_poll_setup(int nfd_in, void *fds_in);
int channel_poll_check(int ret_in, void *fds_in);
int channel_select_setup(int maxfd_in, void *rfds_in);
int channel_select_check(int ret_in, void *rfds_in);
int channel_parse_messages(void);
int set_ref_in_channel(int copyID);
ch_mode_T channel_get_mode(int idx);
ch_mode_T channel_get_mode(channel_T *channel);
/* vim: set ft=c : */
+2 -2
View File
@@ -228,9 +228,9 @@ gui_mch_replace_dialog(exarg_T *eap);
im_set_control(int enable);
void
gui_macvim_add_channel(int idx, int fd);
gui_macvim_add_channel(channel_T *channel);
void
gui_macvim_remove_channel(int idx);
gui_macvim_remove_channel(channel_T *channel);
void
gui_mch_drawsign(int row, int col, int typenr);
+28 -14
View File
@@ -1127,7 +1127,8 @@ typedef enum
VAR_DICT, /* "v_dict" is used */
VAR_FLOAT, /* "v_float" is used */
VAR_SPECIAL, /* "v_number" is used */
VAR_JOB /* "v_job" is used */
VAR_JOB, /* "v_job" is used */
VAR_CHANNEL /* "v_channel" is used */
} vartype_T;
/*
@@ -1148,6 +1149,9 @@ typedef struct
dict_T *v_dict; /* dict value (can be NULL!) */
#ifdef FEAT_JOB
job_T *v_job; /* job value (can be NULL!) */
#endif
#ifdef FEAT_CHANNEL
channel_T *v_channel; /* channel value (can be NULL!) */
#endif
} vval;
} typval_T;
@@ -1260,7 +1264,7 @@ struct jobvar_S
jobstatus_T jv_status;
int jv_refcount; /* reference count */
int jv_channel; /* channel for I/O */
channel_T *jv_channel; /* channel for I/O, reference counted */
};
/*
@@ -1268,35 +1272,41 @@ struct jobvar_S
*/
struct readq_S
{
char_u *buffer;
readq_T *next;
readq_T *prev;
char_u *rq_buffer;
readq_T *rq_next;
readq_T *rq_prev;
};
struct jsonq_S
{
typval_T *value;
jsonq_T *next;
jsonq_T *prev;
typval_T *jq_value;
jsonq_T *jq_next;
jsonq_T *jq_prev;
};
struct cbq_S
{
char_u *callback;
int seq_nr;
cbq_T *next;
cbq_T *prev;
char_u *cq_callback;
int cq_seq_nr;
cbq_T *cq_next;
cbq_T *cq_prev;
};
/* mode for a channel */
typedef enum
{
MODE_RAW = 0,
MODE_NL = 0,
MODE_RAW,
MODE_JSON,
MODE_JS
} ch_mode_T;
struct channel_S {
channel_T *ch_next;
channel_T *ch_prev;
int ch_id; /* ID of the channel */
sock_T ch_sock; /* the socket, -1 for a closed channel */
#ifdef UNIX
@@ -1345,7 +1355,11 @@ struct channel_S {
int ch_timeout; /* request timeout in msec */
job_T *ch_job; /* job that uses this channel */
job_T *ch_job; /* Job that uses this channel; this does not
* count as a reference to avoid a circular
* reference. */
int ch_refcount; /* reference count */
};
+1 -7
View File
@@ -1,13 +1,7 @@
#!/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!')
#
# See ":help channel-demo" in Vim.
# Used by test_channel.vim.
#
# This requires Python 2.6 or later.
+22 -11
View File
@@ -83,7 +83,6 @@ func s:kill_server()
endif
endfunc
let s:responseHandle = -1
let s:responseMsg = ''
func s:RequestHandler(handle, msg)
let s:responseHandle = a:handle
@@ -92,7 +91,7 @@ endfunc
func s:communicate(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if handle < 0
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
return
endif
@@ -115,14 +114,22 @@ func s:communicate(port)
" Send a request with a specific handler.
call ch_sendexpr(handle, 'hello!', 's:RequestHandler')
sleep 10m
call assert_equal(handle, s:responseHandle)
if !exists('s:responseHandle')
call assert_false(1, 's:responseHandle was not set')
else
call assert_equal(handle, s:responseHandle)
endif
call assert_equal('got it', s:responseMsg)
let s:responseHandle = -1
unlet s:responseHandle
let s:responseMsg = ''
call ch_sendexpr(handle, 'hello!', function('s:RequestHandler'))
sleep 10m
call assert_equal(handle, s:responseHandle)
if !exists('s:responseHandle')
call assert_false(1, 's:responseHandle was not set')
else
call assert_equal(handle, s:responseHandle)
endif
call assert_equal('got it', s:responseMsg)
" Send an eval request that works.
@@ -169,7 +176,7 @@ endfunc
" Test that we can open two channels.
func s:two_channels(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if handle < 0
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
return
endif
@@ -177,7 +184,7 @@ func s:two_channels(port)
call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
let newhandle = ch_open('localhost:' . a:port, s:chopt)
if newhandle < 0
if ch_status(newhandle) == "fail"
call assert_false(1, "Can't open second channel")
return
endif
@@ -197,7 +204,7 @@ endfunc
" Test that a server crash is handled gracefully.
func s:server_crash(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if handle < 0
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
return
endif
@@ -219,7 +226,7 @@ endfunc
func s:channel_handler(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if handle < 0
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
return
endif
@@ -245,9 +252,13 @@ endfunc
" Test that trying to connect to a non-existing port fails quickly.
func Test_connect_waittime()
if !has('unix')
" TODO: Make this work again for MS-Windows.
return
endif
let start = reltime()
let handle = ch_open('localhost:9876', s:chopt)
if handle >= 0
if ch_status(handle) == "fail"
" Oops, port does exists.
call ch_close(handle)
else
@@ -257,7 +268,7 @@ func Test_connect_waittime()
let start = reltime()
let handle = ch_open('localhost:9867', {'waittime': 2000})
if handle >= 0
if ch_status(handle) != "fail"
" Oops, port does exists.
call ch_close(handle)
else
+6
View File
@@ -762,6 +762,12 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1317,
/**/
1316,
/**/
1315,
/**/
1314,
/**/