On Mon, Aug 08, 2016 at 03:33:23AM +0200, Ingo Schwarze wrote:
> Hi Dave,
> 
> redirecting from misc@ to tech@ because i'm appending a patch
> at the very end, lightly tested.
> 
> This has indeed been annoying me for years, but it never occurred
> to me that i might be able to figure out what's going on.
> Thanks for providing your analysis, i think it's spot on.
> 
> So the solution is to not swallow up that escape character, right?

Thats not always correct. With your patch ksh now eats the next key you
type when you exit the search prompt with the escape key. The only way
to know whether the esacpe is part of a longer sequence or was typed by
the user is timing. I've sent a patch some time ago that checks if more
bytes are available from the input descriptor to decide whether the esc
was a single one or part of a sequence:
https://marc.info/?l=openbsd-tech&m=141240304628749&w=2

Below an updated version of that patch.

natano


Index: edit.c
===================================================================
RCS file: /cvs/src/bin/ksh/edit.c,v
retrieving revision 1.53
diff -u -p -r1.53 edit.c
--- edit.c      17 Mar 2016 23:33:23 -0000      1.53
+++ edit.c      8 Aug 2016 06:19:34 -0000
@@ -10,6 +10,7 @@
 
 #include <sys/ioctl.h>
 #include <sys/stat.h>
+#include <poll.h>
 
 #include <ctype.h>
 #include <errno.h>
@@ -149,6 +150,16 @@ x_puts(const char *s)
 {
        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.11
diff -u -p -r1.11 edit.h
--- edit.h      26 Jan 2016 17:39:31 -0000      1.11
+++ edit.h      8 Aug 2016 06:19:34 -0000
@@ -39,6 +39,7 @@ int   x_getc(void);
 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.65
diff -u -p -r1.65 emacs.c
--- emacs.c     26 Jan 2016 17:39:31 -0000      1.65
+++ emacs.c     8 Aug 2016 06:19:35 -0000
@@ -893,9 +893,12 @@ x_search_hist(int c)
                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) {


> 
> Yours,
>   Ingo
> 
> 
> Dave Cohen wrote on Sun, Aug 07, 2016 at 04:52:50PM -0700:
> 
> > I'll try to describe an annoyance with my ksh setup.  Web and man
> > page searching has not provided a solution.  I'm relatively new to
> > both ksh and openbsd. I'm on version 5.9 release.
> > 
> > Problem happens when I navigate command history with ctrl-r, then
> > use left or right arrow.  Hitting left arrow writes "[D", right
> > inserts "[C".  I'm hitting the arrow keys so I can edit my prior
> > command.  It's a habit I'm used to that works in bash.
> > 
> > For example to reproduce, let's say I ran "ls -l" but I wanted
> > to run "ls -la"...
> > 
> > run the first command, "ls -l".
> > 
> > type "ctrl-r ls".  This works as expected, and my cursor is now
> > in the middle of "ls -l".
> > 
> > type right arrow.  This is where the problem is.  The command I'm
> > editing becomes "ls[C -l".
> > 
> > From this point, arrow keys work as expected.  I can use left or
> > right to navigate and edit the command.
> > 
> > If, instead of arrows, I use ctrl-b or ctrl-f, these work fine.
> > No artifacts like "[C" or "[D".
> > 
> > If I use bash instead of ksh, this problem does not occur.
> > 
> [...]
> > I understand from `man ksh` that these key bindings are defaults:
> >                    bind '^[[C'=forward-char
> >                    bind '^[[D'=backward-char
> > 
> > My assumption is that when in ctrl-r mode, the '^[' is interpreted
> > as part of the ctrl-r search (which doesn't match), then the '[C'
> > or '[D' is interpreted as the next key (which is inserted).  Can
> > this behavior be changed?
> 
> 
> Index: emacs.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/emacs.c,v
> retrieving revision 1.65
> diff -u -p -r1.65 emacs.c
> --- emacs.c   26 Jan 2016 17:39:31 -0000      1.65
> +++ emacs.c   8 Aug 2016 01:25:13 -0000
> @@ -893,9 +893,10 @@ x_search_hist(int c)
>               if ((c = x_e_getc()) < 0)
>                       return KSTD;
>               f = kb_find_hist_func(c);
> -             if (c == CTRL('['))
> +             if (c == CTRL('[')) {
> +                     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) {
> 

Reply via email to