To: vim_dev@googlegroups.com Subject: Patch 8.0.0932 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0932 Problem: Terminal may not use right characters for BS and Enter. Solution: Get the characters from the tty. Files: src/os_unix.c, src/proto/os_unix.pro, src/terminal.c *** ../vim-8.0.0931/src/os_unix.c 2017-08-11 19:12:05.056966332 +0200 --- src/os_unix.c 2017-08-13 19:44:48.107985184 +0200 *************** *** 365,370 **** --- 365,375 ---- # endif } + /* Why is NeXT excluded here (and not in os_unixx.h)? */ + #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__) + # define NEW_TTY_SYSTEM + #endif + /* * Write s[len] to the screen. */ *************** *** 3385,3395 **** { static int first = TRUE; ! /* Why is NeXT excluded here (and not in os_unixx.h)? */ ! #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__) ! /* ! * for "new" tty systems ! */ # ifdef HAVE_TERMIOS_H static struct termios told; struct termios tnew; --- 3390,3396 ---- { static int first = TRUE; ! #ifdef NEW_TTY_SYSTEM # ifdef HAVE_TERMIOS_H static struct termios told; struct termios tnew; *************** *** 3451,3457 **** # endif #else - /* * for "old" tty systems */ --- 3452,3457 ---- *************** *** 3492,3539 **** void get_stty(void) { ! char_u buf[2]; ! char_u *p; ! /* Why is NeXT excluded here (and not in os_unixx.h)? */ ! #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__) ! /* for "new" tty systems */ # ifdef HAVE_TERMIOS_H struct termios keys; # else struct termio keys; # endif # if defined(HAVE_TERMIOS_H) ! if (tcgetattr(read_cmd_fd, &keys) != -1) # else ! if (ioctl(read_cmd_fd, TCGETA, &keys) != -1) # endif { ! buf[0] = keys.c_cc[VERASE]; ! intr_char = keys.c_cc[VINTR]; #else /* for "old" tty systems */ struct sgttyb keys; ! if (ioctl(read_cmd_fd, TIOCGETP, &keys) != -1) { ! buf[0] = keys.sg_erase; ! intr_char = keys.sg_kill; ! #endif ! buf[1] = NUL; ! add_termcode((char_u *)"kb", buf, FALSE); ! ! /* ! * If and are now the same, redefine . ! */ ! p = find_termcode((char_u *)"kD"); ! if (p != NULL && p[0] == buf[0] && p[1] == buf[1]) ! do_fixdel(NULL); } - #if 0 - } /* to keep cindent happy */ #endif } #endif /* VMS */ --- 3492,3563 ---- void get_stty(void) { ! ttyinfo_T info; ! char_u buf[2]; ! char_u *p; ! if (get_tty_info(read_cmd_fd, &info) == OK) ! { ! intr_char = info.interrupt; ! buf[0] = info.backspace; ! buf[1] = NUL; ! add_termcode((char_u *)"kb", buf, FALSE); ! ! /* If and are now the same, redefine . */ ! p = find_termcode((char_u *)"kD"); ! if (p != NULL && p[0] == buf[0] && p[1] == buf[1]) ! do_fixdel(NULL); ! } ! } ! ! /* ! * Obtain the characters that Backspace and Enter produce on "fd". ! * Returns OK or FAIL. ! */ ! int ! get_tty_info(int fd, ttyinfo_T *info) ! { ! #ifdef NEW_TTY_SYSTEM # ifdef HAVE_TERMIOS_H struct termios keys; # else struct termio keys; # endif + if ( # if defined(HAVE_TERMIOS_H) ! tcgetattr(fd, &keys) != -1 # else ! ioctl(fd, TCGETA, &keys) != -1 # endif + ) { ! info->backspace = keys.c_cc[VERASE]; ! info->interrupt = keys.c_cc[VINTR]; ! if (keys.c_iflag & ICRNL) ! info->enter = NL; ! else ! info->enter = CAR; ! if (keys.c_oflag & ONLCR) ! info->nl_does_cr = TRUE; ! else ! info->nl_does_cr = FALSE; ! return OK; ! } #else /* for "old" tty systems */ struct sgttyb keys; ! if (ioctl(fd, TIOCGETP, &keys) != -1) { ! info->backspace = keys.sg_erase; ! info->interrupt = keys.sg_kill; ! info->enter = CAR; ! info->nl_does_cr = TRUE; ! return OK; } #endif + return FAIL; } #endif /* VMS */ *** ../vim-8.0.0931/src/proto/os_unix.pro 2017-08-11 16:31:50.325234460 +0200 --- src/proto/os_unix.pro 2017-08-13 19:47:06.711105378 +0200 *************** *** 50,55 **** --- 50,56 ---- void mch_exit(int r); void mch_settmode(int tmode); void get_stty(void); + int get_tty_info(int fd, ttyinfo_T *info); void mch_setmouse(int on); void check_mouse_termcode(void); int mch_screenmode(char_u *arg); *** ../vim-8.0.0931/src/terminal.c 2017-08-13 17:38:07.952276754 +0200 --- src/terminal.c 2017-08-13 20:00:42.317941073 +0200 *************** *** 38,48 **** * in tl_scrollback are no longer used. * * TODO: - * - To set BS correctly, check get_stty(); Pass the fd of the pty. - * For the GUI fill termios with default values, perhaps like pangoterm: - * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134 - * Also get the NL behavior from there. - * - do not store terminal window in viminfo. Or prefix term:// ? * - add a character in :ls output * - add 't' to mode() * - use win_del_lines() to make scroll-up efficient. --- 38,43 ---- *************** *** 52,59 **** * - add test for giving error for invalid 'termsize' value. * - support minimal size when 'termsize' is "rows*cols". * - support minimal size when 'termsize' is empty? ! * - implement "term" for job_start(): more job options when starting a ! * terminal. Allow: * "in_io", "in_top", "in_bot", "in_name", "in_buf" "out_io", "out_name", "out_buf", "out_modifiable", "out_msg" "err_io", "err_name", "err_buf", "err_modifiable", "err_msg" --- 47,53 ---- * - add test for giving error for invalid 'termsize' value. * - support minimal size when 'termsize' is "rows*cols". * - support minimal size when 'termsize' is empty? ! * - implement job options when starting a terminal. Allow: * "in_io", "in_top", "in_bot", "in_name", "in_buf" "out_io", "out_name", "out_buf", "out_modifiable", "out_msg" "err_io", "err_name", "err_buf", "err_modifiable", "err_msg" *************** *** 61,66 **** --- 55,62 ---- * Test: "cat" reading from a file or buffer * "ls" writing stdout to a file or buffer * shell writing stderr to a file or buffer + * - For the GUI fill termios with default values, perhaps like pangoterm: + * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134 * - support ":term NONE" to open a terminal with a pty but not running a job * in it. The pty can be passed to gdb to run the executable in. * - if the job in the terminal does not support the mouse, we can use the *************** *** 168,173 **** --- 164,176 ---- static void term_report_winsize(term_T *term, int rows, int cols); static void term_free_vterm(term_T *term); + /* The characters that we know (or assume) that the terminal expects for the + * backspace and enter keys. */ + static int term_backspace_char = BS; + static int term_enter_char = CAR; + static int term_nl_does_cr = FALSE; + + /************************************** * 1. Generic code for all systems. */ *************** *** 552,574 **** size_t done; size_t len_now; ! for (done = 0; done < len; done += len_now) ! { ! for (p = msg + done; p < msg + len; ) ! { ! if (*p == NL) ! break; ! p += utf_ptr2len_len(p, (int)(len - (p - msg))); ! } ! len_now = p - msg - done; ! vterm_input_write(vterm, (char *)msg + done, len_now); ! if (p < msg + len && *p == NL) { ! /* Convert NL to CR-NL, that appears to work best. */ ! vterm_input_write(vterm, "\r\n", 2); ! ++len_now; } - } /* this invokes the damage callbacks */ vterm_screen_flush_damage(vterm_obtain_screen(vterm)); --- 555,580 ---- size_t done; size_t len_now; ! if (term_nl_does_cr) ! vterm_input_write(vterm, (char *)msg, len); ! else ! /* need to convert NL to CR-NL */ ! for (done = 0; done < len; done += len_now) { ! for (p = msg + done; p < msg + len; ) ! { ! if (*p == NL) ! break; ! p += utf_ptr2len_len(p, (int)(len - (p - msg))); ! } ! len_now = p - msg - done; ! vterm_input_write(vterm, (char *)msg + done, len_now); ! if (p < msg + len && *p == NL) ! { ! vterm_input_write(vterm, "\r\n", 2); ! ++len_now; ! } } /* this invokes the damage callbacks */ vterm_screen_flush_damage(vterm_obtain_screen(vterm)); *************** *** 654,663 **** switch (c) { ! case CAR: key = VTERM_KEY_ENTER; break; case ESC: key = VTERM_KEY_ESCAPE; break; - /* VTERM_KEY_BACKSPACE becomes 0x7f DEL */ - case K_BS: c = BS; break; case K_DEL: key = VTERM_KEY_DEL; break; case K_DOWN: key = VTERM_KEY_DOWN; break; case K_S_DOWN: mod = VTERM_MOD_SHIFT; --- 660,671 ---- switch (c) { ! case CAR: c = term_enter_char; break; ! /* don't use VTERM_KEY_BACKSPACE, it always ! * becomes 0x7f DEL */ ! case K_BS: c = term_backspace_char; break; ! case ESC: key = VTERM_KEY_ESCAPE; break; case K_DEL: key = VTERM_KEY_DEL; break; case K_DOWN: key = VTERM_KEY_DOWN; break; case K_S_DOWN: mod = VTERM_MOD_SHIFT; *************** *** 1321,1326 **** --- 1329,1353 ---- position_cursor(curwin, &curbuf->b_term->tl_cursor_pos); may_set_cursor_props(curbuf->b_term); + #ifdef UNIX + { + int fd = curbuf->b_term->tl_job->jv_channel->ch_part[PART_IN].ch_fd; + + if (isatty(fd)) + { + ttyinfo_T info; + + /* Get the current backspace and enter characters of the pty. */ + if (get_tty_info(fd, &info) == OK) + { + term_backspace_char = info.backspace; + term_enter_char = info.enter; + term_nl_does_cr = info.nl_does_cr; + } + } + } + #endif + for (;;) { /* TODO: skip screen update when handling a sequence of keys. */ *** ../vim-8.0.0931/src/version.c 2017-08-13 18:14:42.810655929 +0200 --- src/version.c 2017-08-13 20:05:13.116231149 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 932, /**/ -- "I love deadlines. I especially like the whooshing sound they make as they go flying by." -- Douglas Adams /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///