Patch 7.4.1217
Problem:    Execution of command on channel doesn't work yet.
Solution:   Implement the "ex" and "normal" commands.
Files:      src/channel.c, src/proto/channel.pro, src/misc2.c, src/eval.c,
            src/ex_docmd.c, src/proto/ex_docmd.pro, src/feature.h


*** ../vim-7.4.1216/src/channel.c       2016-01-30 15:14:02.531448995 +0100
--- src/channel.c       2016-01-30 23:15:14.938436609 +0100
***************
*** 99,105 ****
  
      char_u    *ch_callback;   /* function to call when a msg is not handled */
      char_u    *ch_req_callback;       /* function to call for current request 
*/
-     int             ch_will_block;    /* do not use callback right now */
  
      int             ch_json_mode;
  } channel_T;
--- 99,104 ----
***************
*** 419,439 ****
  }
  
  /*
!  * Set the flag that the callback for channel "idx" should not be used now.
!  */
!     void
! channel_will_block(int idx)
! {
!     channels[idx].ch_will_block = TRUE;
! }
! 
! /*
!  * Decode JSON "msg", which must have the form "[nr, expr]".
!  * Put "expr" in "tv".
   * Return OK or FAIL.
   */
      int
! channel_decode_json(char_u *msg, typval_T *tv)
  {
      js_read_T reader;
      typval_T  listtv;
--- 418,430 ----
  }
  
  /*
!  * Decode JSON "msg", which must have the form "[expr1, expr2]".
!  * Put "expr1" in "tv1".
!  * Put "expr2" in "tv2".
   * Return OK or FAIL.
   */
      int
! channel_decode_json(char_u *msg, typval_T *tv1, typval_T *tv2)
  {
      js_read_T reader;
      typval_T  listtv;
***************
*** 442,455 ****
      reader.js_eof = TRUE;
      reader.js_used = 0;
      json_decode(&reader, &listtv);
!     /* TODO: use the sequence number */
!     if (listtv.v_type == VAR_LIST
!         && listtv.vval.v_list->lv_len == 2
!         && listtv.vval.v_list->lv_first->li_tv.v_type == VAR_NUMBER)
      {
        /* Move the item from the list and then change the type to avoid the
         * item being freed. */
!       *tv = listtv.vval.v_list->lv_last->li_tv;
        listtv.vval.v_list->lv_last->li_tv.v_type = VAR_NUMBER;
        list_unref(listtv.vval.v_list);
        return OK;
--- 433,446 ----
      reader.js_eof = TRUE;
      reader.js_used = 0;
      json_decode(&reader, &listtv);
! 
!     if (listtv.v_type == VAR_LIST && listtv.vval.v_list->lv_len == 2)
      {
        /* Move the item from the list and then change the type to avoid the
         * item being freed. */
!       *tv1 = listtv.vval.v_list->lv_first->li_tv;
!       listtv.vval.v_list->lv_first->li_tv.v_type = VAR_NUMBER;
!       *tv2 = listtv.vval.v_list->lv_last->li_tv;
        listtv.vval.v_list->lv_last->li_tv.v_type = VAR_NUMBER;
        list_unref(listtv.vval.v_list);
        return OK;
***************
*** 464,506 ****
   * Invoke the "callback" on channel "idx".
   */
      static void
! invoke_callback(int idx, char_u *callback)
  {
-     typval_T  argv[3];
      typval_T  rettv;
      int               dummy;
-     char_u    *msg;
-     int               ret = OK;
  
      argv[0].v_type = VAR_NUMBER;
      argv[0].vval.v_number = idx;
  
!     /* Concatenate everything into one buffer.
!      * TODO: only read what the callback will use.
!      * TODO: avoid multiple allocations. */
!     while (channel_collapse(idx) == OK)
!       ;
!     msg = channel_get(idx);
  
!     if (channels[idx].ch_json_mode)
!       ret = channel_decode_json(msg, &argv[1]);
!     else
      {
!       argv[1].v_type = VAR_STRING;
!       argv[1].vval.v_string = msg;
      }
! 
!     if (ret == OK)
      {
!       call_func(callback, (int)STRLEN(callback),
!                                &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL);
!       /* If an echo command was used the cursor needs to be put back where
!        * it belongs. */
!       setcursor();
!       cursor_on();
!       out_flush();
      }
!     vim_free(msg);
  }
  
  /*
--- 455,515 ----
   * Invoke the "callback" on channel "idx".
   */
      static void
! invoke_callback(int idx, char_u *callback, typval_T *argv)
  {
      typval_T  rettv;
      int               dummy;
  
      argv[0].v_type = VAR_NUMBER;
      argv[0].vval.v_number = idx;
  
!     call_func(callback, (int)STRLEN(callback),
!                            &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL);
!     /* If an echo command was used the cursor needs to be put back where
!      * it belongs. */
!     setcursor();
!     cursor_on();
!     out_flush();
! }
  
!     static void
! channel_exe_cmd(char_u *cmd, typval_T *arg)
! {
!     if (STRCMP(cmd, "ex") == 0)
      {
!       if (arg->v_type == VAR_STRING)
!           do_cmdline_cmd(arg->vval.v_string);
!       else if (p_verbose > 2)
!           EMSG("E999: received ex command with non-string argument");
      }
!     else if (STRCMP(cmd, "normal") == 0)
      {
!       if (arg->v_type == VAR_STRING)
!       {
!           exarg_T ea;
! 
!           ea.arg = arg->vval.v_string;
!           ea.addr_count = 0;
!           ea.forceit = TRUE; /* no mapping */
!           ex_normal(&ea);
! 
!           update_screen(0);
!           showruler(FALSE);
!           setcursor();
!           out_flush();
! #ifdef FEAT_GUI
!           if (gui.in_use)
!           {
!               gui_update_cursor(FALSE, FALSE);
!               gui_mch_flush();
!           }
! #endif
!       }
!       else if (p_verbose > 2)
!           EMSG("E999: received normal command with non-string argument");
      }
!     else if (p_verbose > 2)
!       EMSG2("E999: received unknown command: %s", cmd);
  }
  
  /*
***************
*** 509,530 ****
      static void
  may_invoke_callback(int idx)
  {
!     if (channels[idx].ch_will_block)
!       return;
      if (channel_peek(idx) == NULL)
        return;
  
!     if (channels[idx].ch_req_callback != NULL)
      {
!       /* invoke the one-time callback */
!       invoke_callback(idx, channels[idx].ch_req_callback);
!       channels[idx].ch_req_callback = NULL;
!       return;
      }
  
!     if (channels[idx].ch_callback != NULL)
!       /* invoke the channel callback */
!       invoke_callback(idx, channels[idx].ch_callback);
  }
  
  /*
--- 518,585 ----
      static void
  may_invoke_callback(int idx)
  {
!     char_u    *msg;
!     typval_T  typetv;
!     typval_T  argv[3];
!     char_u    *cmd = NULL;
!     int               seq_nr = -1;
!     int               ret = OK;
! 
      if (channel_peek(idx) == NULL)
        return;
  
!     /* Concatenate everything into one buffer.
!      * TODO: only read what the callback will use.
!      * TODO: avoid multiple allocations. */
!     while (channel_collapse(idx) == OK)
!       ;
!     msg = channel_get(idx);
! 
!     if (channels[idx].ch_json_mode)
      {
!       ret = channel_decode_json(msg, &typetv, &argv[1]);
!       if (ret == OK)
!       {
!           if (typetv.v_type == VAR_STRING)
!               cmd = typetv.vval.v_string;
!           else if (typetv.v_type == VAR_NUMBER)
!               seq_nr = typetv.vval.v_number;
!       }
!     }
!     else
!     {
!       argv[1].v_type = VAR_STRING;
!       argv[1].vval.v_string = msg;
!     }
! 
!     if (ret == OK)
!     {
!       if (cmd != NULL)
!       {
!           channel_exe_cmd(cmd, &argv[1]);
!       }
!       else if (channels[idx].ch_req_callback != NULL && seq_nr != 0)
!       {
!           /* TODO: check the sequence number */
!           /* invoke the one-time callback */
!           invoke_callback(idx, channels[idx].ch_req_callback, argv);
!           channels[idx].ch_req_callback = NULL;
!       }
!       else if (channels[idx].ch_callback != NULL)
!       {
!           /* invoke the channel callback */
!           invoke_callback(idx, channels[idx].ch_callback, argv);
!       }
!       /* else: drop the message */
! 
!       if (channels[idx].ch_json_mode)
!       {
!           clear_tv(&typetv);
!           clear_tv(&argv[1]);
!       }
      }
  
!     vim_free(msg);
  }
  
  /*
***************
*** 823,830 ****
        }
      }
  
-     may_invoke_callback(idx);
- 
  #if defined(CH_HAS_GUI) && defined(FEAT_GUI_GTK)
      if (CH_HAS_GUI && gtk_main_level() > 0)
        gtk_main_quit();
--- 878,883 ----
***************
*** 845,854 ****
        /* Wait for up to 2 seconds.
         * TODO: use timeout set on the channel. */
        if (channel_wait(channels[idx].ch_fd, 2000) == FAIL)
-       {
-           channels[idx].ch_will_block = FALSE;
            return NULL;
-       }
        channel_read(idx);
      }
  
--- 898,904 ----
***************
*** 857,863 ****
      while (channel_collapse(idx) == OK)
        ;
  
-     channels[idx].ch_will_block = FALSE;
      return channel_get(idx);
  }
  
--- 907,912 ----
***************
*** 1009,1012 ****
--- 1058,1073 ----
  }
  # endif /* !FEAT_GUI_W32 && HAVE_SELECT */
  
+ /*
+  * Invoked from the main loop when it's save to execute received commands.
+  */
+     void
+ channel_parse_messages(void)
+ {
+     int           i;
+ 
+     for (i = 0; i < channel_count; ++i)
+       may_invoke_callback(i);
+ }
+ 
  #endif /* FEAT_CHANNEL */
*** ../vim-7.4.1216/src/proto/channel.pro       2016-01-28 23:10:03.222681092 
+0100
--- src/proto/channel.pro       2016-01-30 22:40:03.888643308 +0100
***************
*** 4,11 ****
  void channel_set_json_mode(int idx, int json_mode);
  void channel_set_callback(int idx, char_u *callback);
  void channel_set_req_callback(int idx, char_u *callback);
! void channel_will_block(int idx);
! int channel_decode_json(char_u *msg, typval_T *tv);
  int channel_is_open(int idx);
  void channel_close(int idx);
  int channel_save(int idx, char_u *buf, int len);
--- 4,10 ----
  void channel_set_json_mode(int idx, int json_mode);
  void channel_set_callback(int idx, char_u *callback);
  void channel_set_req_callback(int idx, char_u *callback);
! int channel_decode_json(char_u *msg, typval_T *tv1, typval_T *tv2);
  int channel_is_open(int idx);
  void channel_close(int idx);
  int channel_save(int idx, char_u *buf, int len);
***************
*** 22,25 ****
--- 21,25 ----
  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);
+ void channel_parse_messages(void);
  /* vim: set ft=c : */
*** ../vim-7.4.1216/src/misc2.c 2016-01-30 21:48:44.325034448 +0100
--- src/misc2.c 2016-01-30 23:19:59.087450391 +0100
***************
*** 6240,6245 ****
--- 6240,6249 ----
      /* Process the queued netbeans messages. */
      netbeans_parse_messages();
  # endif
+ # ifdef FEAT_CHANNEL
+     /* Process the messages queued on channels. */
+     channel_parse_messages();
+ # endif
  # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
      /* Process the queued clientserver messages. */
      server_parse_messages();
*** ../vim-7.4.1216/src/eval.c  2016-01-30 21:48:44.325034448 +0100
--- src/eval.c  2016-01-30 22:39:37.324922720 +0100
***************
*** 16889,16896 ****
       * not reading the response. */
      channel_set_req_callback(ch_idx,
            callback != NULL && *callback == NUL ? NULL : callback);
-     if (callback == NULL)
-       channel_will_block(ch_idx);
  
      if (channel_send(ch_idx, text, fun) == OK && callback == NULL)
        return ch_idx;
--- 16889,16894 ----
***************
*** 16907,16912 ****
--- 16905,16911 ----
      char_u    *resp;
      typval_T  nrtv;
      typval_T  listtv;
+     typval_T  typetv;
      int               ch_idx;
  
      /* return an empty string by default */
***************
*** 16932,16941 ****
      {
        /* TODO: read until the whole JSON message is received */
        /* TODO: only use the message with the right message ID */
        resp = channel_read_block(ch_idx);
        if (resp != NULL)
        {
!           channel_decode_json(resp, rettv);
            vim_free(resp);
        }
      }
--- 16931,16941 ----
      {
        /* TODO: read until the whole JSON message is received */
        /* TODO: only use the message with the right message ID */
+       /* TODO: check sequence number */
        resp = channel_read_block(ch_idx);
        if (resp != NULL)
        {
!           channel_decode_json(resp, &typetv, rettv);
            vim_free(resp);
        }
      }
*** ../vim-7.4.1216/src/ex_docmd.c      2016-01-30 15:52:42.571439521 +0100
--- src/ex_docmd.c      2016-01-30 23:00:16.915878734 +0100
***************
*** 345,351 ****
  static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, 
int *compl);
  #endif
  #ifdef FEAT_EX_EXTRA
- static void   ex_normal(exarg_T *eap);
  static void   ex_startinsert(exarg_T *eap);
  static void   ex_stopinsert(exarg_T *eap);
  #else
--- 345,350 ----
***************
*** 9861,9871 ****
      update_curswant();
  }
  
! #ifdef FEAT_EX_EXTRA
  /*
   * ":normal[!] {commands}": Execute normal mode commands.
   */
!     static void
  ex_normal(exarg_T *eap)
  {
      int               save_msg_scroll = msg_scroll;
--- 9860,9870 ----
      update_curswant();
  }
  
! #if defined(FEAT_EX_EXTRA) || defined(PROTO)
  /*
   * ":normal[!] {commands}": Execute normal mode commands.
   */
!     void
  ex_normal(exarg_T *eap)
  {
      int               save_msg_scroll = msg_scroll;
*** ../vim-7.4.1216/src/proto/ex_docmd.pro      2016-01-21 23:32:14.154035915 
+0100
--- src/proto/ex_docmd.pro      2016-01-30 23:00:19.575850748 +0100
***************
*** 49,54 ****
--- 49,55 ----
  int vim_mkdir_emsg(char_u *name, int prot);
  FILE *open_exfile(char_u *fname, int forceit, char *mode);
  void update_topline_cursor(void);
+ void ex_normal(exarg_T *eap);
  void exec_normal_cmd(char_u *cmd, int remap, int silent);
  void exec_normal(int was_typed);
  int find_cmdline_var(char_u *src, int *usedlen);
*** ../vim-7.4.1216/src/feature.h       2016-01-24 20:36:18.862082391 +0100
--- src/feature.h       2016-01-30 22:55:37.378820167 +0100
***************
*** 256,262 ****
  /*
   * +ex_extra          ":retab", ":right", ":left", ":center", ":normal".
   */
! #ifdef FEAT_NORMAL
  # define FEAT_EX_EXTRA
  #endif
  
--- 256,262 ----
  /*
   * +ex_extra          ":retab", ":right", ":left", ":center", ":normal".
   */
! #if defined(FEAT_NORMAL) || defined(FEAT_CHANNEL)
  # define FEAT_EX_EXTRA
  #endif
  
*** ../vim-7.4.1216/src/version.c       2016-01-30 21:48:44.329034406 +0100
--- src/version.c       2016-01-30 22:35:23.823589506 +0100
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     1217,
  /**/

-- 
>From "know your smileys":
 (:-#   Said something he shouldn't have

 /// 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.

Raspunde prin e-mail lui