| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.431 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.431 |
| Problem: Fetching a key at a prompt may be confused by escape sequences. |
| Especially when getting a prompt at a VimEnter autocommand. |
| (Alex Efros) |
| Solution: Properly handle escape sequences deleted by check_termcode(). |
| Files: src/getchar.c, src/misc1.c, src/term.c, src/proto/term.pro |
| |
| |
| |
| |
| |
| *** 2282,2288 **** |
| typebuf.tb_off] == RM_YES)) |
| && !timedout) |
| { |
| ! keylen = check_termcode(max_mlen + 1, NULL, 0); |
| |
| /* If no termcode matched but 'pastetoggle' |
| * matched partially it's like an incomplete key |
| --- 2282,2289 ---- |
| typebuf.tb_off] == RM_YES)) |
| && !timedout) |
| { |
| ! keylen = check_termcode(max_mlen + 1, |
| ! NULL, 0, NULL); |
| |
| /* If no termcode matched but 'pastetoggle' |
| * matched partially it's like an incomplete key |
| |
| |
| |
| *** 3105,3112 **** |
| int |
| get_keystroke() |
| { |
| ! #define CBUFLEN 151 |
| ! char_u buf[CBUFLEN]; |
| int len = 0; |
| int n; |
| int save_mapped_ctrl_c = mapped_ctrl_c; |
| --- 3105,3113 ---- |
| int |
| get_keystroke() |
| { |
| ! char_u *buf = NULL; |
| ! int buflen = 150; |
| ! int maxlen; |
| int len = 0; |
| int n; |
| int save_mapped_ctrl_c = mapped_ctrl_c; |
| |
| *** 3118,3129 **** |
| cursor_on(); |
| out_flush(); |
| |
| /* First time: blocking wait. Second time: wait up to 100ms for a |
| ! * terminal code to complete. Leave some room for check_termcode() to |
| ! * insert a key code into (max 5 chars plus NUL). And |
| ! * fix_input_buffer() can triple the number of bytes. */ |
| ! n = ui_inchar(buf + len, (CBUFLEN - 6 - len) / 3, |
| ! len == 0 ? -1L : 100L, 0); |
| if (n > 0) |
| { |
| /* Replace zero and CSI by a special key code. */ |
| --- 3119,3147 ---- |
| cursor_on(); |
| out_flush(); |
| |
| + /* Leave some room for check_termcode() to insert a key code into (max |
| + * 5 chars plus NUL). And fix_input_buffer() can triple the number of |
| + * bytes. */ |
| + maxlen = (buflen - 6 - len) / 3; |
| + if (buf == NULL) |
| + buf = alloc(buflen); |
| + else if (maxlen < 10) |
| + { |
| + /* Need some more space. This migth happen when receiving a long |
| + * escape sequence. */ |
| + buflen += 100; |
| + buf = vim_realloc(buf, buflen); |
| + maxlen = (buflen - 6 - len) / 3; |
| + } |
| + if (buf == NULL) |
| + { |
| + do_outofmem_msg((long_u)buflen); |
| + return ESC; /* panic! */ |
| + } |
| + |
| /* First time: blocking wait. Second time: wait up to 100ms for a |
| ! * terminal code to complete. */ |
| ! n = ui_inchar(buf + len, maxlen, len == 0 ? -1L : 100L, 0); |
| if (n > 0) |
| { |
| /* Replace zero and CSI by a special key code. */ |
| |
| *** 3135,3141 **** |
| ++waited; /* keep track of the waiting time */ |
| |
| /* Incomplete termcode and not timed out yet: get more characters */ |
| ! if ((n = check_termcode(1, buf, len)) < 0 |
| && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm))) |
| continue; |
| |
| --- 3153,3159 ---- |
| ++waited; /* keep track of the waiting time */ |
| |
| /* Incomplete termcode and not timed out yet: get more characters */ |
| ! if ((n = check_termcode(1, buf, buflen, &len)) < 0 |
| && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm))) |
| continue; |
| |
| |
| *** 3203,3209 **** |
| { |
| if (MB_BYTE2LEN(n) > len) |
| continue; /* more bytes to get */ |
| ! buf[len >= CBUFLEN ? CBUFLEN - 1 : len] = NUL; |
| n = (*mb_ptr2char)(buf); |
| } |
| #endif |
| --- 3221,3227 ---- |
| { |
| if (MB_BYTE2LEN(n) > len) |
| continue; /* more bytes to get */ |
| ! buf[len >= buflen ? buflen - 1 : len] = NUL; |
| n = (*mb_ptr2char)(buf); |
| } |
| #endif |
| |
| *** 3213,3218 **** |
| --- 3231,3237 ---- |
| #endif |
| break; |
| } |
| + vim_free(buf); |
| |
| mapped_ctrl_c = save_mapped_ctrl_c; |
| return n; |
| |
| |
| |
| *** 3785,3798 **** |
| * With a match, the match is removed, the replacement code is inserted in |
| * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is |
| * returned. |
| ! * When "buf" is not NULL, it is used instead of typebuf.tb_buf[]. "buflen" is |
| ! * then the length of the string in buf[]. |
| */ |
| int |
| ! check_termcode(max_offset, buf, buflen) |
| int max_offset; |
| char_u *buf; |
| ! int buflen; |
| { |
| char_u *tp; |
| char_u *p; |
| --- 3785,3800 ---- |
| * With a match, the match is removed, the replacement code is inserted in |
| * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is |
| * returned. |
| ! * When "buf" is not NULL, buf[bufsize] is used instead of typebuf.tb_buf[]. |
| ! * "buflen" is then the length of the string in buf[] and is updated for |
| ! * inserts and deletes. |
| */ |
| int |
| ! check_termcode(max_offset, buf, bufsize, buflen) |
| int max_offset; |
| char_u *buf; |
| ! int bufsize; |
| ! int *buflen; |
| { |
| char_u *tp; |
| char_u *p; |
| |
| *** 3864,3873 **** |
| } |
| else |
| { |
| ! if (offset >= buflen) |
| break; |
| tp = buf + offset; |
| ! len = buflen - offset; |
| } |
| |
| /* |
| --- 3866,3875 ---- |
| } |
| else |
| { |
| ! if (offset >= *buflen) |
| break; |
| tp = buf + offset; |
| ! len = *buflen - offset; |
| } |
| |
| /* |
| |
| *** 5002,5013 **** |
| if (extra < 0) |
| /* remove matched characters */ |
| mch_memmove(buf + offset, buf + offset - extra, |
| ! (size_t)(buflen + offset + extra)); |
| else if (extra > 0) |
| ! /* insert the extra space we need */ |
| mch_memmove(buf + offset + extra, buf + offset, |
| ! (size_t)(buflen - offset)); |
| mch_memmove(buf + offset, string, (size_t)new_slen); |
| } |
| return retval == 0 ? (len + extra + offset) : retval; |
| } |
| --- 5004,5021 ---- |
| if (extra < 0) |
| /* remove matched characters */ |
| mch_memmove(buf + offset, buf + offset - extra, |
| ! (size_t)(*buflen + offset + extra)); |
| else if (extra > 0) |
| ! { |
| ! /* Insert the extra space we need. If there is insufficient |
| ! * space return -1. */ |
| ! if (*buflen + extra + new_slen >= bufsize) |
| ! return -1; |
| mch_memmove(buf + offset + extra, buf + offset, |
| ! (size_t)(*buflen - offset)); |
| ! } |
| mch_memmove(buf + offset, string, (size_t)new_slen); |
| + *buflen = *buflen + extra + new_slen; |
| } |
| return retval == 0 ? (len + extra + offset) : retval; |
| } |
| |
| |
| |
| *** 50,56 **** |
| char_u *get_termcode __ARGS((int i)); |
| void del_termcode __ARGS((char_u *name)); |
| void set_mouse_topline __ARGS((win_T *wp)); |
| ! int check_termcode __ARGS((int max_offset, char_u *buf, int buflen)); |
| char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part, int do_lt, int special)); |
| int find_term_bykeys __ARGS((char_u *src)); |
| void show_termcodes __ARGS((void)); |
| --- 50,56 ---- |
| char_u *get_termcode __ARGS((int i)); |
| void del_termcode __ARGS((char_u *name)); |
| void set_mouse_topline __ARGS((win_T *wp)); |
| ! int check_termcode __ARGS((int max_offset, char_u *buf, int bufsize, int *buflen)); |
| char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part, int do_lt, int special)); |
| int find_term_bykeys __ARGS((char_u *src)); |
| void show_termcodes __ARGS((void)); |
| |
| |
| |
| *** 716,717 **** |
| --- 716,719 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 431, |
| /**/ |
| |
| -- |
| "You know, it's at times like this when I'm trapped in a Vogon airlock with |
| a man from Betelgeuse and about to die of asphyxiation in deep space that I |
| really wish I'd listened to what my mother told me when I was young!" |
| "Why, what did she tell you?" |
| "I don't know, I didn't listen!" |
| -- Arthur Dent and Ford Prefect in Douglas Adams' |
| "The Hitchhiker's Guide to the Galaxy" |
| |
| /// 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 /// |