The following patch fixes a bug in ksh I reported some time ago (http://marc.info/?l=openbsd-bugs&m=137292039914229&w=2). I committed this patch to Bitrig in December 2013; it seems to work fine so far.
Here the bug report inline for reference. > Description: When using a keybinding that starts with ^[ while in history search mode in ksh, history search is aborted and the rest of the keybinding is printed at the current cursor position. search-history is implemented in x_search_hist in bin/ksh/emacs.c. x_search_hist returns on the first ^[ character in the input stream, so the remaining characters of the escape sequence are interpreted by x_emacs. e.g.: pressing the left arrow key when in search mode inserts "[D" at the cursor position. > How-To-Repeat: set -o emacs Type ^R. Use arrow key or home/end. Some garbage is printed at the cursor position. > Fix: unknown FYI: bash assumes that ^[ is part of a longer keybinding when more characters arrive in a duration of 0.1 seconds, but that looks like an ugly solution to me. Anyone cares to commit (or comment)? cheers, natano --- Only consume ^[ in search mode when not part of an escape sequence Index: edit.c =================================================================== RCS file: /cvs/src/bin/ksh/edit.c,v retrieving revision 1.39 diff -u -r1.39 edit.c --- edit.c 17 Dec 2013 16:37:05 -0000 1.39 +++ edit.c 3 Oct 2014 20:45:35 -0000 @@ -17,6 +17,7 @@ #include <ctype.h> #include <libgen.h> #include <sys/stat.h> +#include <poll.h> static void x_sigwinch(int); @@ -145,6 +146,16 @@ { while (*s != 0) shf_putc(*s++, shl_out); +} + +int +x_avail(void) +{ + struct pollfd pfd[1]; + + pfd[0].fd = STDIN_FILENO; + pfd[0].events = POLLIN; + return poll(pfd, 1, 0) == 1; } bool Index: edit.h =================================================================== RCS file: /cvs/src/bin/ksh/edit.h,v retrieving revision 1.9 diff -u -r1.9 edit.h --- edit.h 30 May 2011 17:14:35 -0000 1.9 +++ edit.h 3 Oct 2014 20:45:35 -0000 @@ -48,6 +48,7 @@ void x_flush(void); void x_putc(int); void x_puts(const char *); +int x_avail(void); bool x_mode(bool); int promptlen(const char *, const char **); int x_do_comment(char *, int, int *); Index: emacs.c =================================================================== RCS file: /cvs/src/bin/ksh/emacs.c,v retrieving revision 1.48 diff -u -r1.48 emacs.c --- emacs.c 17 Dec 2013 16:37:05 -0000 1.48 +++ emacs.c 3 Oct 2014 20:45:35 -0000 @@ -884,9 +884,12 @@ if ((c = x_e_getc()) < 0) return KSTD; f = kb_find_hist_func(c); - if (c == CTRL('[')) + if (c == CTRL('[')) { + /* might be part of an escape sequence */ + if (x_avail()) + x_e_ungetc(c); break; - else if (f == x_search_hist) + } else if (f == x_search_hist) offset = x_search(pat, 0, offset); else if (f == x_del_back) { if (p == pat) {