comparison src/terminal.c @ 12800:8dfeed7e07e7 v8.0.1277

patch 8.0.1277: terminal window CR-NL conversions may cause problems commit https://github.com/vim/vim/commit/26d205dcd886b48713f22cbdbf2a8e55400083dc Author: Bram Moolenaar <Bram@vim.org> Date: Thu Nov 9 17:33:11 2017 +0100 patch 8.0.1277: terminal window CR-NL conversions may cause problems Problem: Terminal window CR-NL conversions may cause problems. Solution: Avoid most conversions, only fetch the current backspace key value from the tty. (mostly by Ozaki Kiichi, closes #2278)
author Christian Brabandt <cb@256bit.org>
date Thu, 09 Nov 2017 17:45:05 +0100
parents 5ae0d05e046a
children 15696054bc6c
comparison
equal deleted inserted replaced
12799:a27dc6d11c0a 12800:8dfeed7e07e7
179 static int term_and_job_init(term_T *term, typval_T *argvar, jobopt_T *opt); 179 static int term_and_job_init(term_T *term, typval_T *argvar, jobopt_T *opt);
180 static int create_pty_only(term_T *term, jobopt_T *opt); 180 static int create_pty_only(term_T *term, jobopt_T *opt);
181 static void term_report_winsize(term_T *term, int rows, int cols); 181 static void term_report_winsize(term_T *term, int rows, int cols);
182 static void term_free_vterm(term_T *term); 182 static void term_free_vterm(term_T *term);
183 183
184 /* The characters that we know (or assume) that the terminal expects for the 184 /* The character that we know (or assume) that the terminal expects for the
185 * backspace and enter keys. */ 185 * backspace key. */
186 static int term_backspace_char = BS; 186 static int term_backspace_char = BS;
187 static int term_enter_char = CAR;
188 static int term_nl_does_cr = FALSE;
189 187
190 188
191 /************************************** 189 /**************************************
192 * 1. Generic code for all systems. 190 * 1. Generic code for all systems.
193 */ 191 */
649 */ 647 */
650 static void 648 static void
651 term_write_job_output(term_T *term, char_u *msg, size_t len) 649 term_write_job_output(term_T *term, char_u *msg, size_t len)
652 { 650 {
653 VTerm *vterm = term->tl_vterm; 651 VTerm *vterm = term->tl_vterm;
654 char_u *p; 652
655 size_t done; 653 vterm_input_write(vterm, (char *)msg, len);
656 size_t len_now;
657
658 if (term_nl_does_cr)
659 vterm_input_write(vterm, (char *)msg, len);
660 else
661 /* need to convert NL to CR-NL */
662 for (done = 0; done < len; done += len_now)
663 {
664 for (p = msg + done; p < msg + len; )
665 {
666 if (*p == NL)
667 break;
668 p += utf_ptr2len_len(p, (int)(len - (p - msg)));
669 }
670 len_now = p - msg - done;
671 vterm_input_write(vterm, (char *)msg + done, len_now);
672 if (p < msg + len && *p == NL)
673 {
674 vterm_input_write(vterm, "\r\n", 2);
675 ++len_now;
676 }
677 }
678 654
679 /* this invokes the damage callbacks */ 655 /* this invokes the damage callbacks */
680 vterm_screen_flush_damage(vterm_obtain_screen(vterm)); 656 vterm_screen_flush_damage(vterm_obtain_screen(vterm));
681 } 657 }
682 658
758 VTermModifier mod = VTERM_MOD_NONE; 734 VTermModifier mod = VTERM_MOD_NONE;
759 int mouse = FALSE; 735 int mouse = FALSE;
760 736
761 switch (c) 737 switch (c)
762 { 738 {
763 case CAR: c = term_enter_char; break; 739 /* don't use VTERM_KEY_ENTER, it may do an unwanted conversion */
740
764 /* don't use VTERM_KEY_BACKSPACE, it always 741 /* don't use VTERM_KEY_BACKSPACE, it always
765 * becomes 0x7f DEL */ 742 * becomes 0x7f DEL */
766 case K_BS: c = term_backspace_char; break; 743 case K_BS: c = term_backspace_char; break;
767 744
768 case ESC: key = VTERM_KEY_ESCAPE; break; 745 case ESC: key = VTERM_KEY_ESCAPE; break;
1532 { 1509 {
1533 int c; 1510 int c;
1534 int termkey = 0; 1511 int termkey = 0;
1535 int ret; 1512 int ret;
1536 #ifdef UNIX 1513 #ifdef UNIX
1537 int tty_fd = curbuf->b_term->tl_job->jv_channel->ch_part[get_tty_part(curbuf->b_term)].ch_fd; 1514 int tty_fd = curbuf->b_term->tl_job->jv_channel
1515 ->ch_part[get_tty_part(curbuf->b_term)].ch_fd;
1538 #endif 1516 #endif
1539 1517
1540 /* Remember the terminal we are sending keys to. However, the terminal 1518 /* Remember the terminal we are sending keys to. However, the terminal
1541 * might be closed while waiting for a character, e.g. typing "exit" in a 1519 * might be closed while waiting for a character, e.g. typing "exit" in a
1542 * shell and ++close was used. Therefore use curbuf->b_term instead of a 1520 * shell and ++close was used. Therefore use curbuf->b_term instead of a
1555 while (must_redraw != 0) 1533 while (must_redraw != 0)
1556 if (update_screen(0) == FAIL) 1534 if (update_screen(0) == FAIL)
1557 break; 1535 break;
1558 update_cursor(curbuf->b_term, FALSE); 1536 update_cursor(curbuf->b_term, FALSE);
1559 1537
1538 c = term_vgetc();
1539 if (!term_use_loop())
1540 {
1541 /* Job finished while waiting for a character. Push back the
1542 * received character. */
1543 if (c != K_IGNORE)
1544 vungetc(c);
1545 break;
1546 }
1547 if (c == K_IGNORE)
1548 continue;
1549
1560 #ifdef UNIX 1550 #ifdef UNIX
1561 /* 1551 /*
1562 * The shell or another program may change the tty settings. Getting 1552 * The shell or another program may change the tty settings. Getting
1563 * them for every typed character is a bit of overhead, but it's needed 1553 * them for every typed character is a bit of overhead, but it's needed
1564 * for the first CR typed, e.g. when Vim starts in a shell. 1554 * for the first character typed, e.g. when Vim starts in a shell.
1565 */ 1555 */
1566 if (isatty(tty_fd)) 1556 if (isatty(tty_fd))
1567 { 1557 {
1568 ttyinfo_T info; 1558 ttyinfo_T info;
1569 1559
1570 /* Get the current backspace and enter characters of the pty. */ 1560 /* Get the current backspace character of the pty. */
1571 if (get_tty_info(tty_fd, &info) == OK) 1561 if (get_tty_info(tty_fd, &info) == OK)
1572 {
1573 term_backspace_char = info.backspace; 1562 term_backspace_char = info.backspace;
1574 term_enter_char = info.enter;
1575 term_nl_does_cr = info.nl_does_cr;
1576 }
1577 } 1563 }
1578 #endif 1564 #endif
1579
1580 c = term_vgetc();
1581 if (!term_use_loop())
1582 {
1583 /* job finished while waiting for a character */
1584 if (c != K_IGNORE)
1585 vungetc(c);
1586 break;
1587 }
1588 if (c == K_IGNORE)
1589 continue;
1590 1565
1591 #ifdef WIN3264 1566 #ifdef WIN3264
1592 /* On Windows winpty handles CTRL-C, don't send a CTRL_C_EVENT. 1567 /* On Windows winpty handles CTRL-C, don't send a CTRL_C_EVENT.
1593 * Use CTRL-BREAK to kill the job. */ 1568 * Use CTRL-BREAK to kill the job. */
1594 if (ctrl_break_was_pressed) 1569 if (ctrl_break_was_pressed)