Bug #6601

[readline] Alt-* commands do not work in reverse-i-search

Added by Tay Ray Chuan almost 2 years ago. Updated almost 2 years ago.

[ruby-core:45682]
Status:Closed
Priority:Normal
Assignee:Kouji Takao
Category:ext
Target version:1.9.3
ruby -v:ruby 1.9.3p236 (2012-06-11) [x86_64-linux] Backport:

Description

=begin
= Steps to reproduce
Below are the steps to reproduce from an (({irb})) session. ^ is used to denote the cursor position on the screen.

  • Type ((%puts :a%)) then ((%Enter%)). This is to populate the history for reverse-i-search.
    irb(main):001:0> puts :a
    a
    => nil

  • Hit ((%Ctrl-R%)) (for reverse-i-search), followed by ((%u%)):
    (reverse-i-search)`u': puts :a
    ^

  • Hit ((%Alt-F%)) (for forward-word).

Observed: reverse-i-search terminated, with an 'f' inserted at cursor position.
irb(main):002:0> pfuts :a
^

Expected: reverse-i-search terminated, nothing inserted, cursor moves to end of the word (({puts})):
irb(main):002:0> puts :a
^

Note that other ((%Alt-*%)) commands don't work too (ie ((%x%)) is inserted instead of the command ((%Alt-x%)) being performed), including

  • ((%Alt-B%)) (move backward a word)
  • ((%Alt-C%)) (capitalize letter)
  • ((%Alt-D%)) (delete till end of word)

= Fix

When we hit ((%Alt-F%)) from reverse-i-search, execution arrives at this piece of code in libreadline's (({isearch.c})):

387 /* ESC still terminates the search, but if there is pending
388 input or if input arrives within 0.1 seconds (on systems
389 with select(2)) it is used as a prefix character
390 with rlexecutenext. WATCH OUT FOR THIS! This is intended
391 to allow the arrow keys to be used like F and B are used
392 to terminate the search and execute the movement command.
393 XXX - since rlinputavailable depends on the application-
394 settable keyboard timeout value, this could alternatively
395 use _rl
inputqueued(100000) */
396 if (cxt->lastc == ESC && _rl
inputavailable ())
397 rl
execute_next (ESC);

Due to (({readlinegetc()})), our (({rlgetcfunction()})) implementation, (({IO::getbyte()})) is called, causing all input characters to be "swallowed" into our byte buffer in (({readlineinstream})). Thus (({rlinput_available()})) incorrectly returns false, and the keystrokes (eg. Alt, F) fail to be recognized as a binding for a command.

The proposed fix (attached) uses (({rbioreadpending()})) to emulate (({rlinputavailable()})), and calls (({rlexecutenext()})), as libreadline does.

= Affected Versions

Ruby trunk and 1.9.3 (latest) exhibits this issue.

Ruby 1.8 also has exhibits this issue, but the fix would be different since (({rlgetcfunction()})) isn't overriden in (({ext/readline/readline.c})).

Tested on readline 6.2; blame'ing the above snippet shows that readline as far back as 5.1 should also give this behaviour.

=end

readline.diff Magnifier - applies cleanly on trunk and Backport93 (852 Bytes) Tay Ray Chuan, 06/17/2012 05:23 PM


Related issues

Related to ruby-trunk - Bug #6262: [readline] reverse-i-search with multibyte chars Closed 04/06/2012

Associated revisions

Revision 36123
Added by Nobuyoshi Nakada almost 2 years ago

ext/readline/readline.c: [Bug #6601]

  • ext/readline/readline.c (readline_getc): deal with ESC just followed by ASCII as meta prefix in incremental search mode. based on the patch from rctay (Tay Ray Chuan) at . [Bug #6601]

Revision 36127
Added by Yui NARUSE almost 2 years ago

  • ext/readline/readline.c (readline_getc): fix editline compatibility broken by r36123. [Bug #6601]

History

#1 Updated by Tay Ray Chuan almost 2 years ago

Oops, forgot to enter a proper title/subject. Can someone with sufficient privileges update it to

[readline] Alt-* commands do not work in reverse-i-search

? Many thanks.

#2 Updated by Nobuyoshi Nakada almost 2 years ago

  • Subject changed from [readline] to [readline] Alt-* commands do not work in reverse-i-search
  • Category set to ext
  • Status changed from Open to Assigned
  • Assignee set to Kouji Takao
  • Target version set to 1.9.3

#3 Updated by Nobuyoshi Nakada almost 2 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r36123.
Tay, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


ext/readline/readline.c: [Bug #6601]

  • ext/readline/readline.c (readline_getc): deal with ESC just followed by ASCII as meta prefix in incremental search mode. based on the patch from rctay (Tay Ray Chuan) at . [Bug #6601]

#4 Updated by Eric Hodel almost 2 years ago

  • Status changed from Closed to Assigned

=begin
This breaks compilation on OS X 10.7 with editline:

compiling readline.c
readline.c:177:22: error: use of undeclared identifier 'ESC'
if (c == INT2FIX(ESC) &&
^
../.././include/ruby/ruby.h:228:45: note: expanded from macro 'INT2FIX'
#define INT2FIX(i) ((VALUE)(((SIGNEDVALUE)(i))<<1 | FIXNUMFLAG))
^
readline.c:178:2: warning: implicit declaration of function 'RLISSTATE' is
invalid in C99 [-Wimplicit-function-declaration]
RL
ISSTATE(RLSTATEISEARCH) && /* isn't needed in other states? /
^
readline.c:178:13: error: use of undeclared identifier 'RLSTATEISEARCH'
RLISSTATE(RLSTATE_ISEARCH) && /
isn't needed in other states? */
^
readline.c:182:21: warning: implicit declaration of function 'isascii' is
invalid in C99 [-Wimplicit-function-declaration]
if (FIXNUMP(c) && isascii(FIX2INT(c))) meta = 1;
^
readline.c:184:12: warning: implicit declaration of function 'rl
executenext'
is invalid in C99 [-Wimplicit-function-declaration]
if (meta) rl
executenext(ESC);
^
readline.c:184:28: error: use of undeclared identifier 'ESC'
if (meta) rl
execute_next(ESC);
^
readline.c:185:9: error: use of undeclared identifier 'ESC'
return ESC;
^

editline does not have the ESC macro not the rlreadlinestate variable (for RL_ISSTATE)

Checking for rlreadlinestate in extconf.rb allows the second chunk of this patch to be ignored when compiled against editline, but I'm unsure how to update the test to get it to pass.
=end

#5 Updated by Yui NARUSE almost 2 years ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r36127.
Tay, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • ext/readline/readline.c (readline_getc): fix editline compatibility broken by r36123. [Bug #6601]

Also available in: Atom PDF