To: vim_dev@googlegroups.com Subject: Patch 7.4.1624 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1624 Problem: Can't get info about a channel. Solution: Add ch_info(). Files: src/eval.c, src/channel.c, src/proto/channel.pro, src/testdir/test_channel.vim, runtime/doc/eval.txt *** ../vim-7.4.1623/src/eval.c 2016-03-19 22:11:47.416675050 +0100 --- src/eval.c 2016-03-20 19:41:45.594981836 +0100 *************** *** 501,506 **** --- 501,507 ---- 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_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_logfile(typval_T *argvars, typval_T *rettv); static void f_ch_open(typval_T *argvars, typval_T *rettv); *************** *** 8141,8146 **** --- 8142,8148 ---- {"ch_evalraw", 2, 3, f_ch_evalraw}, {"ch_getbufnr", 2, 2, f_ch_getbufnr}, {"ch_getjob", 1, 1, f_ch_getjob}, + {"ch_info", 1, 1, f_ch_info}, {"ch_log", 1, 2, f_ch_log}, {"ch_logfile", 1, 2, f_ch_logfile}, {"ch_open", 1, 2, f_ch_open}, *************** *** 10029,10034 **** --- 10031,10048 ---- } /* + * "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 */ static void *** ../vim-7.4.1623/src/channel.c 2016-03-20 19:31:28.893299230 +0100 --- src/channel.c 2016-03-20 20:35:42.165731539 +0100 *************** *** 838,843 **** --- 838,845 ---- channel->CH_SOCK_FD = (sock_T)sd; 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 channel_gui_register_one(channel, PART_SOCK); *************** *** 1138,1143 **** --- 1140,1149 ---- ch_logs(channel, "writing err to buffer '%s'", (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,2093 **** --- 2094,2162 ---- 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". * Trigger the close callback if "invoke_close_cb" is TRUE. *************** *** 2195,2200 **** --- 2264,2271 ---- channel_clear(channel_T *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_OUT); channel_clear_one(channel, PART_ERR); *** ../vim-7.4.1623/src/proto/channel.pro 2016-03-20 19:31:28.893299230 +0100 --- src/proto/channel.pro 2016-03-20 19:54:11.287365909 +0100 *************** *** 20,25 **** --- 20,26 ---- int channel_can_write_to(channel_T *channel); int channel_is_open(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); char_u *channel_peek(channel_T *channel, int part); void channel_clear(channel_T *channel); *** ../vim-7.4.1623/src/testdir/test_channel.vim 2016-03-20 16:40:33.218484399 +0100 --- src/testdir/test_channel.vim 2016-03-20 20:34:54.942228924 +0100 *************** *** 120,128 **** return endif if has('job') ! " check that no job is handled correctly call assert_equal('no process', string(ch_getjob(handle))) endif " Simple string request and reply. call assert_equal('got it', ch_evalexpr(handle, 'hello!')) --- 120,135 ---- return endif if has('job') ! " check that getjob without a job is handled correctly call assert_equal('no process', string(ch_getjob(handle))) 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. call assert_equal('got it', ch_evalexpr(handle, 'hello!')) *** ../vim-7.4.1623/runtime/doc/eval.txt 2016-03-15 23:10:26.412712095 +0100 --- runtime/doc/eval.txt 2016-03-20 20:30:47.880819768 +0100 *************** *** 1803,1826 **** call( {func}, {arglist} [, {dict}]) any call {func} with arguments {arglist} ceil( {expr}) Float round {expr} up ! ch_close( {channel}) none close {channel} ! ch_evalexpr( {channel}, {expr} [, {options}]) ! any evaluate {expr} on JSON {channel} ! ch_evalraw( {channel}, {string} [, {options}]) ! any evaluate {string} on raw {channel} ! ch_getbufnr( {channel}, {what}) Number get buffer number for {channel}/{what} ch_getjob( {channel}) Job get the Job of {channel} ! ch_log( {msg} [, {channel}]) none write {msg} in the channel log file ch_logfile( {fname} [, {mode}]) none start logging channel activity ch_open( {address} [, {options}]) Channel open a channel to {address} ! ch_read( {channel} [, {options}]) String read from {channel} ! ch_readraw( {channel} [, {options}]) String read raw from {channel} ! ch_sendexpr( {channel}, {expr} [, {options}]) ! any send {expr} over JSON {channel} ! ch_sendraw( {channel}, {string} [, {options}]) ! any send {string} over raw {channel} ! ch_setoptions( {channel}, {options}) none set options for {channel} ! ch_status( {channel}) String status of {channel} 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,1844 ---- call( {func}, {arglist} [, {dict}]) any call {func} with arguments {arglist} ceil( {expr}) Float round {expr} up ! ch_close( {handle}) none close {handle} ! ch_evalexpr( {handle}, {expr} [, {options}]) ! any evaluate {expr} on JSON {handle} ! ch_evalraw( {handle}, {string} [, {options}]) ! any evaluate {string} on raw {handle} ! ch_getbufnr( {handle}, {what}) Number get buffer number for {handle}/{what} 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_logfile( {fname} [, {mode}]) none start logging channel activity ch_open( {address} [, {options}]) Channel open a channel to {address} ! ch_read( {handle} [, {options}]) String read from {handle} ! ch_readraw( {handle} [, {options}]) String read raw from {handle} ! ch_sendexpr( {handle}, {expr} [, {options}]) ! any send {expr} over JSON {handle} ! ch_sendraw( {handle}, {string} [, {options}]) ! any send {string} over raw {handle} ! ch_setoptions( {handle}, {options}) none set options for {handle} ! ch_status( {handle}) String status of 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} *************** *** 2731,2741 **** {only available when compiled with the |+channel| and |+job| features} ! ch_log({msg} [, {channel}]) *ch_log()* Write {msg} in the channel log file, if it was opened with |ch_logfile()|. ! When {channel} is passed the channel number is used for the ! message. {channel} must be an open channel. ch_logfile({fname} [, {mode}]) *ch_logfile()* Start logging channel activity to {fname}. --- 2765,2803 ---- {only available when compiled with the |+channel| and |+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()* Write {msg} in the channel log file, if it was opened with |ch_logfile()|. ! When {handle} is passed the channel number is used for the ! message. ! {handle} can be Channel or a Job that has a Channel. The ! Channel must open. ch_logfile({fname} [, {mode}]) *ch_logfile()* Start logging channel activity to {fname}. *** ../vim-7.4.1623/src/version.c 2016-03-20 19:31:28.897299188 +0100 --- src/version.c 2016-03-20 19:40:52.475524030 +0100 *************** *** 750,751 **** --- 750,753 ---- { /* Add new patch number below this line */ + /**/ + 1624, /**/ -- From "know your smileys": :'-D Laughing so much that they're crying /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 ///