Mercurial > vim
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) |