bugGNU Octave - Bugs: bug #49323, Readline library does not support...

 
 

bug #49323: Readline library does not support vi-mode correctly

Submitter:  Rik <rik5>
Submitted:  Wed 12 Oct 2016 06:06:17 PM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Thu 13 Oct 2016 10:36:27 PM UTC, comment #18: 

I downloaded and built a local copy of readline 7.0 and lo--the problem is solved.  That's a way better resolution to this report than I was expecting.

Rik <rik5>
Group administrator
Thu 13 Oct 2016 05:32:25 PM UTC, comment #17: 

I can't seem to reproduce the problem with readline 7.0.

John W. Eaton <jwe>
Group administrator
Thu 13 Oct 2016 05:20:31 PM UTC, comment #16: 

I haven't yet, but I can try it.

John W. Eaton <jwe>
Group administrator
Thu 13 Oct 2016 05:13:19 PM UTC, comment #15: 

Can you test / have you tested with readline 7.0 that was released about 4 weeks ago? I assume Chet would prefer that this has been tested on the latest release before reporting.

Mike Miller <mtmiller>
Group Member
Thu 13 Oct 2016 04:00:07 PM UTC, comment #14: 

If you want me to, but I'm not the vi user.  :-)

John W. Eaton <jwe>
Group administrator
Thu 13 Oct 2016 03:41:27 PM UTC, comment #13: 

Marking the bug as postponed since this needs an upstream fix. 

Are you going to report it to Readline?

Rik <rik5>
Group administrator
Thu 13 Oct 2016 03:38:29 PM UTC, comment #12: 

Report the bug for readline.  Here is a minimal example that allows me to demonstrate the problem:


#include <stdio.h>
#include <readline/readline.h>

static int
event_hook (void)
{
  return 0;
}

int
main (void)
{
  rl_event_hook = event_hook;

  while (1)
    printf ("==> %s\n", readline (">>> "));

  return 0;
}


On my system, I just need to use "gcc foo.c -lreadline" to compile it.  Then run the program and enter vi editing mode, either by setting it in an inputrc file or by using M-C-m to switch the mode.  Then I can get characters to randomly disappear just by typing something and then using the left arrow key to move the cursor.  History is not needed to show the problem.  Just vi mode and a trivial event function.

John W. Eaton <jwe>
Group administrator
Thu 13 Oct 2016 03:31:19 AM UTC, comment #11: 

That is surely at the root of the problem.


octave-cli -f
graphics_toolkit gnuplot
function f () end
123<Left Arrow>  # works
add_input_event_hook ('f');
123<Left Arrow>  # broken
remove_input_event_hook ('f');
123<Left Arrow>  # works


The fact that it is completely reversible by removing the event hook function means the diagnosis is probably correct.

What's to be done?  The 'XXX' comment looks like it might be marking something experimental.  The 'XXX' is beside the call to the rl_gather_tyi function which gives me little confidence.

Rik <rik5>
Group administrator
Thu 13 Oct 2016 02:37:34 AM UTC, comment #10: 

I see the problem any time there is an input event hook function installed.  FLTK does that.

So, can you try starting Octave and setting the toolkit to gnuplot and see if the funny behavior goes away?

And then do this (still with gnuplot for graphics) to see if the problem returns:


function f () end
add_input_event_hook (@f);


I see this problem just by adding the empty event hook function.

If you look at the function rl_read_key in input.c in the readline sources, you can see that there are two separate code paths for the case of having an event hook function or not having one.  I guess this screws up vi mode somehow.  It doesn't seem to cause trouble for the emacs mode.

Here is that code from readline's input.c from the Debian package:


      /* If the user has an event function, then call it periodically. */
      if (rl_event_hook)
        {
          while (rl_event_hook)
            {
              if (rl_get_char (&c) != 0)
                break;

              if ((r = rl_gather_tyi ()) < 0)   /* XXX - EIO */
                {
                  rl_done = 1;
                  return ('\n');
                }
              else if (r > 0)                   /* read something */
                continue;

              RL_CHECK_SIGNALS ();
              if (rl_done)              /* XXX - experimental */
                return ('\n');
              (*rl_event_hook) ();
            }
        }
      else
        {
          if (rl_get_char (&c) == 0)
            c = (*rl_getc_function) (rl_instream);
/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */
          RL_CHECK_SIGNALS ();
        }


By default, rl_getc_function is rl_getc, which is considerably different from rl_gather_tyi.

John W. Eaton <jwe>
Group administrator
Thu 13 Oct 2016 02:01:11 AM UTC, comment #9: 

For what it's worth, my version of readline is 6.3-8ubuntu1.  I only see the issue when the editing-mode is set to vi.  Maybe this is some sort of memory corruption?  It is very odd because even the right arrow key causes a deletion.

Test ~/.inputrc file


set editing-mode vi
set keymap vi-command
"\C-f": dump-functions
"\C-g": dump-macros
set keymap vi-insert
"\e[D": "Hello"
"\C-f": dump-functions
"\C-g": dump-macros
set show-mode-in-prompt on
set keyseq-timeout 250


Thes maps the left arrow to produce the text "Hello".


octave-cli -f -q
12<Left Arrow>   # This will correctly insert "Hello" after 12
graphics_toolkit fltk
123<Left Arrow>  # '3' is deleted, cursor moves to 2, mode changes to command
# Change .inputrc to map Left Arrow to "bye"
readline_read_init_file ("~/.inputrc")
<Ctrl+g>
\e[D outputs bye
123<Left Arrow>  # '3' is deleted, cursor moves to 2, mode changes to command


From the last test, I can see that Readline knows what it should be generating, but it isn't doing it.  Is it possible that the terminal is now producing a different escape sequence for the left arrow that doesn't match "\e[D"?


Rik <rik5>
Group administrator
Thu 13 Oct 2016 01:40:28 AM UTC, comment #8: 

I checked in the change to have the user's inputrc override Octave's (http://hg.savannah.gnu.org/hgweb/octave/rev/51b7d8456ce3).

That still leaves the weird behavior I am seeing with the left arrow key after calling graphics_toolkit.

Rik <rik5>
Group administrator
Wed 12 Oct 2016 11:44:42 PM UTC, comment #7: 

Don't forget to clear the inputrc variable so it's not left in the user's workspace.

Mike Miller <mtmiller>
Group Member
Wed 12 Oct 2016 10:17:45 PM UTC, comment #6: 

This stanza works for me and respects the INPUTRC environment variable.


inputrc = getenv ("INPUTRC");
if (isempty (inputrc) && exist ("~/.inputrc", "file"))
  inputrc = "~/.inputrc";
endif
if (! isempty (inputrc))
  readline_read_init_file (inputrc);
endif



Rik <rik5>
Group administrator
Wed 12 Oct 2016 10:11:15 PM UTC, comment #5: 

Yes, I've had


  read_readline_init_file ("~/.inputrc");


in my ~/.octaverc for a long time now, to ensure that my preferences get loaded after Octave's site inputrc is loaded.

Mike Miller <mtmiller>
Group Member
Wed 12 Oct 2016 09:50:36 PM UTC, comment #4: 

After a little more reading, I think the stanza is almost correct.  First, however, need to check for an environment variable INPUTRC, and if that is empty then check for ~/.inputrc.

Rik <rik5>
Group administrator
Wed 12 Oct 2016 09:40:37 PM UTC, comment #3: 

This seems to be related, but we are overriding parts of the user's inputrc with Octave's sitewide version.  With the .inputrc file from comment #2, try


octave-cli --no-init-file
<Ctrl+g>
\C-v outputs


Despite having mapping the up arrow to "Hello" there is no mention of it.

Now try


octave-cli --no-site-file
<Ctrl+g>
\e[A outputs Hello


This is good.  And what I've not done is run the sitewide octaverc file.


## Configure readline using the file inputrc in the Octave startup directory.
readline_read_init_file (sprintf ("%s%s%s",
                                  __octave_config_info__ ("startupfiledir"),
                                  filesep, "inputrc"));


The sitewide inputrc file is


## This file configures the behavior of line-input editing for all
## Octave users when Octave is configured to use GNU Readline library
## for input-line editing.

## history-search-backward:
##
##   Search backward through the history for the string of characters
##   between the start of the current line and the point.  This is a
##   non-incremental search.  Bound to "\e[A", the ANSI escape
##   sequence for the UP arrow.

"\e[A": history-search-backward

## history-search-forward:
##
##   Search forward through the history for the string of characters
##   between the start of the current line and the point.  This is a
##   non-incremental search.  Bound to "\e[B", the ANSI escape
##   sequence for the DOWN arrow.

"\e[B": history-search-forward

## Disable so the usual paste shortcut will work on Windows systems.
## \C-q should still be available for quoted insert.

"\C-v": ""

## In windows, disable audiable bell which is enabled by default
$if term=cygwin
   set bell-style none
$endif


We shouldn't be overriding user selections like this.  I would propose adding this stanza to the sitewide octaverc file after the first call to readline_read_init_file.


if (exist ("~/.inputrc", "file"))
  readline_read_init_file ("~/.inputrc");
endif


I tested it and it works for me.

Rik <rik5>
Group administrator
Wed 12 Oct 2016 09:11:07 PM UTC, comment #2: 

It seems there is quite a bit going on.  Try this .inputrc file:


set editing-mode vi
set show-mode-in-prompt on
set keyseq-timeout 250

set keymap vi-insert
"\e[A": "Hello"

"\C-f": dump-functions
"\C-g": dump-macros

set keymap vi-command

"\C-f": dump-functions
"\C-g": dump-macros


Now, if you start a bash shell you can type Ctrl+g to see what macros are defined.  There should be only the one that substitutes "Hello" each time the up arrow key is pressed.  Verify that this macro works.

I am using a up-to-date version of octave that I install in a local directory.  For this sequence, the first left arrow works correctly.  However, after I have switched toolkits, it fails.


octave-cli -f
123<left arrow><return>
graphics_toolkit fltk
123<left arrow>


Interestingly enough, the default toolkit on start-up is already fltk.  Also, setting the graphics toolkit to gnuplot, rather than fltk, doesn't create a problem.  Nor does setting the toolkit to 'qt' which emits an error because the CLI is not linked with qt.

The test below already fails on the first time even though fltk is not the default toolkit for the --no-gui option.


octave -f --no-gui
123<left arrow>



Rik <rik5>
Group administrator
Wed 12 Oct 2016 06:57:31 PM UTC, comment #1: 

I don't see that behavior.  I created a ~/.inputrc file with the two lines


set editing-mode vi
set show-mode-in-prompt on


Then I'm starting Octave (stable build, HG ID = 96411a33f570) with ./run-octave -cli (so no GUI libs) and I see a + at the beginning of the prompt.  Then if I type up arrow, it moves to the previous history line and remains in insert mode with the cursor at the end of the line.  Using the left arrow moves the cursor back toward the prompt (nothing is deleted) and I stay in insert mode.  That makes sense to me as I just want to move around with the arrow key and be ready to insert something.

Bash behaves the same way on my system.

I have libreadline 6.3-8+b4 on a Debian system.

John W. Eaton <jwe>
Group administrator
Wed 12 Oct 2016 06:06:17 PM UTC, original submission:  

The Readline library supports both vi and emacs key bindings.  Emacs is the default setting.  Readline can be configured for any application (not just Octave) through the file ~/.inputrc.  In my file the first line is


set editing-mode vi


to switch all key bindings over to vi-compatible ones.

This works perfectly in tcsh (which I use) or in csh.  In Octave, however, there is a problem switching between insert and command mode.  By default, a new line should be in "insert" mode (set keymap vi-insert).  This allows one to immediately start typing.  That part is correct in Octave.  When I type an up-arrow, to get the command up-history, Octave/Readline should switch to "command" mode and display the last line on the console.  Instead, Octave is remaining in insert mode.  When I then type a left arrow to move one character to the left, Octave pauses a bit and then deletes the last character and drops into command mode.  To see what I mean, try adding


set show-mode-in-prompt on


to ~/.inputrc and re-start Octave.

Now there will be an indication at the start of the line as to which mode the Readline library is in.  For me, '+' indicates insert and ':' indicates command.  I can verify the sequence above is exactly what is happening.

This is terribly annoying as I keep ending up with garbled commands.  Incidentally, all of this is console behavior when run with --no-gui-libs.  The issue has been present in Octave a long time as I've verified the behavior back to 3.4.3.

Now, this may not actually be Octave's fault.  tcsh has it's own internal line editing commands using bindkey so it may not be using the Readline library.  If I start a bash shell, I find that the insert mode persists if I use an up-arrow to call up-history.  Maybe Octave could be throwing a call to rl_set_keymap at that point, if in vi mode.  But at least when I use the left arrow key in Bash it moves the cursor, rather than causing a delete operation.

In the end, maybe only the 'left arrow' issue is a true Octave problem.

Rik <rik5>
Group administrator

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by rik5 (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-10-13 rik5 StatusPostponed Fixed
        Open/ClosedOpen Closed
    2016-10-13 rik5 StatusNone Postponed

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code