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) {