comparison src/channel.c @ 8422:5d2c84be23b5 v7.4.1502

commit https://github.com/vim/vim/commit/99ef06296f3c37490511c03786a2c8672e015c56 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Mar 6 20:22:25 2016 +0100 patch 7.4.1502 Problem: Writing last-but-one line of buffer to a channel isn't implemented yet. Solution: Implement it. Fix leaving a swap file behind.
author Christian Brabandt <cb@256bit.org>
date Sun, 06 Mar 2016 20:30:04 +0100
parents 05ec48deb353
children 4e22d0e7bfb1
comparison
equal deleted inserted replaced
8421:4be5f7dd51dc 8422:5d2c84be23b5
835 835
836 in_part->ch_buffer = job->jv_in_buf; 836 in_part->ch_buffer = job->jv_in_buf;
837 ch_logs(channel, "reading from buffer '%s'", 837 ch_logs(channel, "reading from buffer '%s'",
838 (char *)in_part->ch_buffer->b_ffname); 838 (char *)in_part->ch_buffer->b_ffname);
839 if (options->jo_set & JO_IN_TOP) 839 if (options->jo_set & JO_IN_TOP)
840 in_part->ch_buf_top = options->jo_in_top; 840 {
841 if (options->jo_in_top == 0 && !(options->jo_set & JO_IN_BOT))
842 {
843 /* Special mode: send last-but-one line when appending a line
844 * to the buffer. */
845 in_part->ch_buffer->b_write_to_channel = TRUE;
846 in_part->ch_buf_top =
847 in_part->ch_buffer->b_ml.ml_line_count + 1;
848 }
849 else
850 in_part->ch_buf_top = options->jo_in_top;
851 }
841 else 852 else
842 in_part->ch_buf_top = 1; 853 in_part->ch_buf_top = 1;
843 if (options->jo_set & JO_IN_BOT) 854 if (options->jo_set & JO_IN_BOT)
844 in_part->ch_buf_bot = options->jo_in_bot; 855 in_part->ch_buf_bot = options->jo_in_bot;
845 else 856 else
862 { 873 {
863 buf = buflist_new(name == NULL || *name == NUL ? NULL : name, 874 buf = buflist_new(name == NULL || *name == NUL ? NULL : name,
864 NULL, (linenr_T)0, BLN_LISTED); 875 NULL, (linenr_T)0, BLN_LISTED);
865 buf_copy_options(buf, BCO_ENTER); 876 buf_copy_options(buf, BCO_ENTER);
866 #ifdef FEAT_QUICKFIX 877 #ifdef FEAT_QUICKFIX
867 clear_string_option(&buf->b_p_bt); 878 set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
868 buf->b_p_bt = vim_strsave((char_u *)"nofile"); 879 set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
869 clear_string_option(&buf->b_p_bh);
870 buf->b_p_bh = vim_strsave((char_u *)"hide");
871 #endif 880 #endif
872 curbuf = buf; 881 curbuf = buf;
873 ml_open(curbuf); 882 if (curbuf->b_ml.ml_mfp == NULL)
883 ml_open(curbuf);
874 ml_replace(1, (char_u *)"Reading from channel output...", TRUE); 884 ml_replace(1, (char_u *)"Reading from channel output...", TRUE);
875 changed_bytes(1, 0); 885 changed_bytes(1, 0);
876 curbuf = save_curbuf; 886 curbuf = save_curbuf;
877 } 887 }
878 888
980 else 990 else
981 item->cq_prev->cq_next = item; 991 item->cq_prev->cq_next = item;
982 } 992 }
983 } 993 }
984 994
985 /* 995 static void
986 * Write any lines to the in channel. 996 write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
997 {
998 char_u *line = ml_get_buf(buf, lnum, FALSE);
999 int len = STRLEN(line);
1000 char_u *p;
1001
1002 /* TODO: check if channel can be written to, do not block on write */
1003 if ((p = alloc(len + 2)) == NULL)
1004 return;
1005 STRCPY(p, line);
1006 p[len] = NL;
1007 p[len + 1] = NUL;
1008 channel_send(channel, PART_IN, p, "write_buf_line()");
1009 vim_free(p);
1010 }
1011
1012 /*
1013 * Write any lines to the input channel.
987 */ 1014 */
988 void 1015 void
989 channel_write_in(channel_T *channel) 1016 channel_write_in(channel_T *channel)
990 { 1017 {
991 chanpart_T *in_part = &channel->ch_part[PART_IN]; 1018 chanpart_T *in_part = &channel->ch_part[PART_IN];
992 linenr_T lnum; 1019 linenr_T lnum;
993 buf_T *buf = in_part->ch_buffer; 1020 buf_T *buf = in_part->ch_buffer;
1021 int written = 0;
994 1022
995 if (buf == NULL) 1023 if (buf == NULL)
996 return; 1024 return;
997 if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL) 1025 if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL)
998 { 1026 {
1005 return; 1033 return;
1006 1034
1007 for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot 1035 for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot
1008 && lnum <= buf->b_ml.ml_line_count; ++lnum) 1036 && lnum <= buf->b_ml.ml_line_count; ++lnum)
1009 { 1037 {
1010 char_u *line = ml_get_buf(buf, lnum, FALSE); 1038 write_buf_line(buf, lnum, channel);
1011 int len = STRLEN(line); 1039 ++written;
1012 char_u *p; 1040 }
1013 1041
1014 /* TODO: check if channel can be written to */ 1042 if (written == 1)
1015 if ((p = alloc(len + 2)) == NULL) 1043 ch_logn(channel, "written line %d to channel", (int)lnum - 1);
1016 break; 1044 else if (written > 1)
1017 STRCPY(p, line); 1045 ch_logn(channel, "written %d lines to channel", written);
1018 p[len] = NL; 1046
1019 p[len + 1] = NUL;
1020 channel_send(channel, PART_IN, p, "channel_write_in()");
1021 vim_free(p);
1022 }
1023 in_part->ch_buf_top = lnum; 1047 in_part->ch_buf_top = lnum;
1048 }
1049
1050 /*
1051 * Write appended lines above the last one in "buf" to the channel.
1052 */
1053 void
1054 channel_write_new_lines(buf_T *buf)
1055 {
1056 channel_T *channel;
1057 int found_one = FALSE;
1058
1059 /* There could be more than one channel for the buffer, loop over all of
1060 * them. */
1061 for (channel = first_channel; channel != NULL; channel = channel->ch_next)
1062 {
1063 chanpart_T *in_part = &channel->ch_part[PART_IN];
1064 linenr_T lnum;
1065 int written = 0;
1066
1067 if (in_part->ch_buffer == buf)
1068 {
1069 if (in_part->ch_fd == INVALID_FD)
1070 /* pipe was closed */
1071 continue;
1072 found_one = TRUE;
1073 for (lnum = in_part->ch_buf_bot; lnum < buf->b_ml.ml_line_count;
1074 ++lnum)
1075 {
1076 write_buf_line(buf, lnum, channel);
1077 ++written;
1078 }
1079
1080 if (written == 1)
1081 ch_logn(channel, "written line %d to channel", (int)lnum - 1);
1082 else if (written > 1)
1083 ch_logn(channel, "written %d lines to channel", written);
1084
1085 in_part->ch_buf_bot = lnum;
1086 }
1087 }
1088 if (!found_one)
1089 buf->b_write_to_channel = FALSE;
1024 } 1090 }
1025 1091
1026 /* 1092 /*
1027 * Invoke the "callback" on channel "channel". 1093 * Invoke the "callback" on channel "channel".
1028 */ 1094 */
1468 invoke_callback(channel, item->cq_callback, argv); 1534 invoke_callback(channel, item->cq_callback, argv);
1469 vim_free(item->cq_callback); 1535 vim_free(item->cq_callback);
1470 vim_free(item); 1536 vim_free(item);
1471 } 1537 }
1472 1538
1539 static void
1540 append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel)
1541 {
1542 buf_T *save_curbuf = curbuf;
1543 linenr_T lnum = buffer->b_ml.ml_line_count;
1544 int save_write_to = buffer->b_write_to_channel;
1545
1546 /* If the buffer is also used as input insert above the last
1547 * line. Don't write these lines. */
1548 if (save_write_to)
1549 {
1550 --lnum;
1551 buffer->b_write_to_channel = FALSE;
1552 }
1553
1554 /* Append to the buffer */
1555 ch_logn(channel, "appending line %d to buffer", (int)lnum + 1);
1556
1557 curbuf = buffer;
1558 u_sync(TRUE);
1559 /* ignore undo failure, undo is not very useful here */
1560 ignored = u_save(lnum, lnum + 1);
1561
1562 ml_append(lnum, msg, 0, FALSE);
1563 appended_lines_mark(lnum, 1L);
1564 curbuf = save_curbuf;
1565
1566 if (buffer->b_nwindows > 0)
1567 {
1568 win_T *wp;
1569 win_T *save_curwin;
1570
1571 FOR_ALL_WINDOWS(wp)
1572 {
1573 if (wp->w_buffer == buffer
1574 && (save_write_to
1575 ? wp->w_cursor.lnum == lnum + 1
1576 : (wp->w_cursor.lnum == lnum
1577 && wp->w_cursor.col == 0)))
1578 {
1579 ++wp->w_cursor.lnum;
1580 save_curwin = curwin;
1581 curwin = wp;
1582 curbuf = curwin->w_buffer;
1583 scroll_cursor_bot(0, FALSE);
1584 curwin = save_curwin;
1585 curbuf = curwin->w_buffer;
1586 }
1587 }
1588 redraw_buf_later(buffer, VALID);
1589 channel_need_redraw = TRUE;
1590 }
1591
1592 if (save_write_to)
1593 {
1594 channel_T *ch;
1595
1596 /* Find channels reading from this buffer and adjust their
1597 * next-to-read line number. */
1598 buffer->b_write_to_channel = TRUE;
1599 for (ch = first_channel; ch != NULL; ch = ch->ch_next)
1600 {
1601 chanpart_T *in_part = &ch->ch_part[PART_IN];
1602
1603 if (in_part->ch_buffer == buffer)
1604 in_part->ch_buf_bot = buffer->b_ml.ml_line_count;
1605 }
1606 }
1607 }
1608
1473 /* 1609 /*
1474 * Invoke a callback for "channel"/"part" if needed. 1610 * Invoke a callback for "channel"/"part" if needed.
1475 * Return TRUE when a message was handled, there might be another one. 1611 * Return TRUE when a message was handled, there might be another one.
1476 */ 1612 */
1477 static int 1613 static int
1632 { 1768 {
1633 if (msg == NULL) 1769 if (msg == NULL)
1634 /* JSON or JS mode: re-encode the message. */ 1770 /* JSON or JS mode: re-encode the message. */
1635 msg = json_encode(listtv, ch_mode); 1771 msg = json_encode(listtv, ch_mode);
1636 if (msg != NULL) 1772 if (msg != NULL)
1637 { 1773 append_to_buffer(buffer, msg, channel);
1638 buf_T *save_curbuf = curbuf;
1639 linenr_T lnum = buffer->b_ml.ml_line_count;
1640
1641 /* Append to the buffer */
1642 ch_logn(channel, "appending line %d to buffer", (int)lnum + 1);
1643
1644 curbuf = buffer;
1645 u_sync(TRUE);
1646 /* ignore undo failure, undo is not very useful here */
1647 ignored = u_save(lnum, lnum + 1);
1648
1649 ml_append(lnum, msg, 0, FALSE);
1650 appended_lines_mark(lnum, 1L);
1651 curbuf = save_curbuf;
1652
1653 if (buffer->b_nwindows > 0)
1654 {
1655 win_T *wp;
1656 win_T *save_curwin;
1657
1658 FOR_ALL_WINDOWS(wp)
1659 {
1660 if (wp->w_buffer == buffer
1661 && wp->w_cursor.lnum == lnum
1662 && wp->w_cursor.col == 0)
1663 {
1664 ++wp->w_cursor.lnum;
1665 save_curwin = curwin;
1666 curwin = wp;
1667 curbuf = curwin->w_buffer;
1668 scroll_cursor_bot(0, FALSE);
1669 curwin = save_curwin;
1670 curbuf = curwin->w_buffer;
1671 }
1672 }
1673 redraw_buf_later(buffer, VALID);
1674 channel_need_redraw = TRUE;
1675 }
1676 }
1677 } 1774 }
1678 1775
1679 if (callback != NULL) 1776 if (callback != NULL)
1680 { 1777 {
1681 if (cbitem != NULL) 1778 if (cbitem != NULL)