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