comparison src/channel.c @ 7864:6b0891de44a9 v7.4.1229

commit https://github.com/vim/vim/commit/fb1f62691eae7c79a28b3b17a60e72ce198c71a2 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 31 20:24:32 2016 +0100 patch 7.4.1229 Problem: "eval" and "expr" channel commands don't work yet. Solution: Implement them. Update the error numbers. Also add "redraw".
author Christian Brabandt <cb@256bit.org>
date Sun, 31 Jan 2016 20:30:04 +0100
parents 28f569c7dab9
children 17e6ff1a74f1
comparison
equal deleted inserted replaced
7863:e18a688b2e3b 7864:6b0891de44a9
291 291
292 idx = add_channel(); 292 idx = add_channel();
293 if (idx < 0) 293 if (idx < 0)
294 { 294 {
295 CHERROR("All channels are in use\n", ""); 295 CHERROR("All channels are in use\n", "");
296 EMSG(_("E999: All channels are in use")); 296 EMSG(_("E897: All channels are in use"));
297 return -1; 297 return -1;
298 } 298 }
299 299
300 if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1) 300 if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1)
301 { 301 {
302 CHERROR("error in socket() in channel_open()\n", ""); 302 CHERROR("error in socket() in channel_open()\n", "");
303 PERROR("E999: socket() in channel_open()"); 303 PERROR("E898: socket() in channel_open()");
304 return -1; 304 return -1;
305 } 305 }
306 306
307 /* Get the server internet address and put into addr structure */ 307 /* Get the server internet address and put into addr structure */
308 /* fill in the socket address structure and connect to server */ 308 /* fill in the socket address structure and connect to server */
310 server.sin_family = AF_INET; 310 server.sin_family = AF_INET;
311 server.sin_port = htons(port); 311 server.sin_port = htons(port);
312 if ((host = gethostbyname(hostname)) == NULL) 312 if ((host = gethostbyname(hostname)) == NULL)
313 { 313 {
314 CHERROR("error in gethostbyname() in channel_open()\n", ""); 314 CHERROR("error in gethostbyname() in channel_open()\n", "");
315 PERROR("E999: gethostbyname() in channel_open()"); 315 PERROR("E901: gethostbyname() in channel_open()");
316 sock_close(sd); 316 sock_close(sd);
317 return -1; 317 return -1;
318 } 318 }
319 memcpy((char *)&server.sin_addr, host->h_addr, host->h_length); 319 memcpy((char *)&server.sin_addr, host->h_addr, host->h_length);
320 320
328 sock_close(sd); 328 sock_close(sd);
329 if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1) 329 if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1)
330 { 330 {
331 SOCK_ERRNO; 331 SOCK_ERRNO;
332 CHERROR("socket() retry in channel_open()\n", ""); 332 CHERROR("socket() retry in channel_open()\n", "");
333 PERROR("E999: socket() retry in channel_open()"); 333 PERROR("E900: socket() retry in channel_open()");
334 return -1; 334 return -1;
335 } 335 }
336 if (connect(sd, (struct sockaddr *)&server, sizeof(server))) 336 if (connect(sd, (struct sockaddr *)&server, sizeof(server)))
337 { 337 {
338 int retries = 36; 338 int retries = 36;
360 } 360 }
361 if (!success) 361 if (!success)
362 { 362 {
363 /* Get here when the server can't be found. */ 363 /* Get here when the server can't be found. */
364 CHERROR("Cannot connect to port after retry\n", ""); 364 CHERROR("Cannot connect to port after retry\n", "");
365 PERROR(_("E999: Cannot connect to port after retry2")); 365 PERROR(_("E899: Cannot connect to port after retry2"));
366 sock_close(sd); 366 sock_close(sd);
367 return -1; 367 return -1;
368 } 368 }
369 } 369 }
370 } 370 }
371 else 371 else
372 { 372 {
373 CHERROR("Cannot connect to port\n", ""); 373 CHERROR("Cannot connect to port\n", "");
374 PERROR(_("E999: Cannot connect to port")); 374 PERROR(_("E902: Cannot connect to port"));
375 sock_close(sd); 375 sock_close(sd);
376 return -1; 376 return -1;
377 } 377 }
378 } 378 }
379 379
416 channels[idx].ch_req_callback = callback == NULL 416 channels[idx].ch_req_callback = callback == NULL
417 ? NULL : vim_strsave(callback); 417 ? NULL : vim_strsave(callback);
418 } 418 }
419 419
420 /* 420 /*
421 * Decode JSON "msg", which must have the form "[expr1, expr2]". 421 * Decode JSON "msg", which must have the form "[expr1, expr2, expr3]".
422 * Put "expr1" in "tv1". 422 * Put "expr1" in "tv1".
423 * Put "expr2" in "tv2". 423 * Put "expr2" in "tv2".
424 * Put "expr3" in "tv3". If "tv3" is NULL there is no "expr3".
425 *
424 * Return OK or FAIL. 426 * Return OK or FAIL.
425 */ 427 */
426 int 428 int
427 channel_decode_json(char_u *msg, typval_T *tv1, typval_T *tv2) 429 channel_decode_json(char_u *msg, typval_T *tv1, typval_T *tv2, typval_T *tv3)
428 { 430 {
429 js_read_T reader; 431 js_read_T reader;
430 typval_T listtv; 432 typval_T listtv;
431 433
432 reader.js_buf = msg; 434 reader.js_buf = msg;
433 reader.js_eof = TRUE; 435 reader.js_eof = TRUE;
434 reader.js_used = 0; 436 reader.js_used = 0;
435 json_decode(&reader, &listtv); 437 json_decode(&reader, &listtv);
436 438
437 if (listtv.v_type == VAR_LIST && listtv.vval.v_list->lv_len == 2) 439 if (listtv.v_type == VAR_LIST)
438 { 440 {
439 /* Move the item from the list and then change the type to avoid the 441 list_T *list = listtv.vval.v_list;
440 * item being freed. */ 442
441 *tv1 = listtv.vval.v_list->lv_first->li_tv; 443 if (list->lv_len == 2 || (tv3 != NULL && list->lv_len == 3))
442 listtv.vval.v_list->lv_first->li_tv.v_type = VAR_NUMBER; 444 {
443 *tv2 = listtv.vval.v_list->lv_last->li_tv; 445 /* Move the item from the list and then change the type to avoid the
444 listtv.vval.v_list->lv_last->li_tv.v_type = VAR_NUMBER; 446 * item being freed. */
445 list_unref(listtv.vval.v_list); 447 *tv1 = list->lv_first->li_tv;
446 return OK; 448 list->lv_first->li_tv.v_type = VAR_NUMBER;
449 *tv2 = list->lv_first->li_next->li_tv;
450 list->lv_first->li_next->li_tv.v_type = VAR_NUMBER;
451 if (tv3 != NULL)
452 {
453 if (list->lv_len == 3)
454 {
455 *tv3 = list->lv_last->li_tv;
456 list->lv_last->li_tv.v_type = VAR_NUMBER;
457 }
458 else
459 tv3->v_type = VAR_UNKNOWN;
460 }
461 list_unref(list);
462 return OK;
463 }
447 } 464 }
448 465
449 /* give error message? */ 466 /* give error message? */
450 clear_tv(&listtv); 467 clear_tv(&listtv);
451 return FAIL; 468 return FAIL;
470 setcursor(); 487 setcursor();
471 cursor_on(); 488 cursor_on();
472 out_flush(); 489 out_flush();
473 } 490 }
474 491
492 /*
493 * Execute a command received over channel "idx".
494 * "cmd" is the command string, "arg2" the second argument.
495 * "arg3" is the third argument, NULL if missing.
496 */
475 static void 497 static void
476 channel_exe_cmd(char_u *cmd, typval_T *arg) 498 channel_exe_cmd(int idx, char_u *cmd, typval_T *arg2, typval_T *arg3)
477 { 499 {
500 char_u *arg;
501
502 if (arg2->v_type != VAR_STRING)
503 {
504 if (p_verbose > 2)
505 EMSG("E903: received ex command with non-string argument");
506 return;
507 }
508 arg = arg2->vval.v_string;
509
478 if (STRCMP(cmd, "ex") == 0) 510 if (STRCMP(cmd, "ex") == 0)
479 { 511 {
480 if (arg->v_type == VAR_STRING) 512 do_cmdline_cmd(arg);
481 do_cmdline_cmd(arg->vval.v_string);
482 else if (p_verbose > 2)
483 EMSG("E999: received ex command with non-string argument");
484 } 513 }
485 else if (STRCMP(cmd, "normal") == 0) 514 else if (STRCMP(cmd, "normal") == 0)
486 { 515 {
487 if (arg->v_type == VAR_STRING) 516 exarg_T ea;
488 { 517
489 exarg_T ea; 518 ea.arg = arg;
490 519 ea.addr_count = 0;
491 ea.arg = arg->vval.v_string; 520 ea.forceit = TRUE; /* no mapping */
492 ea.addr_count = 0; 521 ex_normal(&ea);
493 ea.forceit = TRUE; /* no mapping */ 522 }
494 ex_normal(&ea); 523 else if (STRCMP(cmd, "redraw") == 0)
495 524 {
496 update_screen(0); 525 exarg_T ea;
497 showruler(FALSE); 526
498 setcursor(); 527 ea.forceit = *arg != NUL;
499 out_flush(); 528 ex_redraw(&ea);
529 showruler(FALSE);
530 setcursor();
531 out_flush();
500 #ifdef FEAT_GUI 532 #ifdef FEAT_GUI
501 if (gui.in_use) 533 if (gui.in_use)
534 {
535 gui_update_cursor(FALSE, FALSE);
536 gui_mch_flush();
537 }
538 #endif
539 }
540 else if (STRCMP(cmd, "expr") == 0 || STRCMP(cmd, "eval") == 0)
541 {
542 int is_eval = cmd[1] == 'v';
543
544 if (is_eval && arg3->v_type != VAR_NUMBER)
545 {
546 if (p_verbose > 2)
547 EMSG("E904: third argument for eval must be a number");
548 }
549 else
550 {
551 typval_T *tv = eval_expr(arg, NULL);
552 typval_T err_tv;
553 char_u *json;
554
555 if (is_eval)
502 { 556 {
503 gui_update_cursor(FALSE, FALSE); 557 if (tv == NULL)
504 gui_mch_flush(); 558 {
559 err_tv.v_type = VAR_STRING;
560 err_tv.vval.v_string = (char_u *)"ERROR";
561 tv = &err_tv;
562 }
563 json = json_encode_nr_expr(arg3->vval.v_number, tv);
564 channel_send(idx, json, "eval");
565 vim_free(json);
505 } 566 }
506 #endif 567 free_tv(tv);
507 } 568 }
508 else if (p_verbose > 2)
509 EMSG("E999: received normal command with non-string argument");
510 } 569 }
511 else if (p_verbose > 2) 570 else if (p_verbose > 2)
512 EMSG2("E999: received unknown command: %s", cmd); 571 EMSG2("E905: received unknown command: %s", cmd);
513 } 572 }
514 573
515 /* 574 /*
516 * Invoke a callback for channel "idx" if needed. 575 * Invoke a callback for channel "idx" if needed.
517 */ 576 */
519 may_invoke_callback(int idx) 578 may_invoke_callback(int idx)
520 { 579 {
521 char_u *msg; 580 char_u *msg;
522 typval_T typetv; 581 typval_T typetv;
523 typval_T argv[3]; 582 typval_T argv[3];
583 typval_T arg3;
524 char_u *cmd = NULL; 584 char_u *cmd = NULL;
525 int seq_nr = -1; 585 int seq_nr = -1;
526 int ret = OK; 586 int ret = OK;
527 587
528 if (channel_peek(idx) == NULL) 588 if (channel_peek(idx) == NULL)
535 ; 595 ;
536 msg = channel_get(idx); 596 msg = channel_get(idx);
537 597
538 if (channels[idx].ch_json_mode) 598 if (channels[idx].ch_json_mode)
539 { 599 {
540 ret = channel_decode_json(msg, &typetv, &argv[1]); 600 ret = channel_decode_json(msg, &typetv, &argv[1], &arg3);
541 if (ret == OK) 601 if (ret == OK)
542 { 602 {
603 /* TODO: error if arg3 is set when it shouldn't? */
543 if (typetv.v_type == VAR_STRING) 604 if (typetv.v_type == VAR_STRING)
544 cmd = typetv.vval.v_string; 605 cmd = typetv.vval.v_string;
545 else if (typetv.v_type == VAR_NUMBER) 606 else if (typetv.v_type == VAR_NUMBER)
546 seq_nr = typetv.vval.v_number; 607 seq_nr = typetv.vval.v_number;
547 } 608 }
554 615
555 if (ret == OK) 616 if (ret == OK)
556 { 617 {
557 if (cmd != NULL) 618 if (cmd != NULL)
558 { 619 {
559 channel_exe_cmd(cmd, &argv[1]); 620 channel_exe_cmd(idx, cmd, &argv[1], &arg3);
560 } 621 }
561 else if (channels[idx].ch_req_callback != NULL && seq_nr != 0) 622 else if (channels[idx].ch_req_callback != NULL && seq_nr != 0)
562 { 623 {
563 /* TODO: check the sequence number */ 624 /* TODO: check the sequence number */
564 /* invoke the one-time callback */ 625 /* invoke the one-time callback */
574 635
575 if (channels[idx].ch_json_mode) 636 if (channels[idx].ch_json_mode)
576 { 637 {
577 clear_tv(&typetv); 638 clear_tv(&typetv);
578 clear_tv(&argv[1]); 639 clear_tv(&argv[1]);
640 clear_tv(&arg3);
579 } 641 }
580 } 642 }
581 643
582 vim_free(msg); 644 vim_free(msg);
583 } 645 }
872 934
873 if (len < 0) 935 if (len < 0)
874 { 936 {
875 /* Todo: which channel? */ 937 /* Todo: which channel? */
876 CHERROR("%s(): cannot from channel\n", "channel_read"); 938 CHERROR("%s(): cannot from channel\n", "channel_read");
877 PERROR(_("E999: read from channel")); 939 PERROR(_("E896: read from channel"));
878 } 940 }
879 } 941 }
880 942
881 #if defined(CH_HAS_GUI) && defined(FEAT_GUI_GTK) 943 #if defined(CH_HAS_GUI) && defined(FEAT_GUI_GTK)
882 if (CH_HAS_GUI && gtk_main_level() > 0) 944 if (CH_HAS_GUI && gtk_main_level() > 0)