You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In macOS (I am using Monterey 12.1), the home and end keys no longer move the cursor to the start of the line and the end of the line respectively. Instead, these keys output the escape sequences you see in the screenshot below.
This behavior is new in irb that ships with Ruby 3.1. In the previous version, these keys worked as expected.
Result of irb_info
Ruby version: 3.1.0
IRB version: irb 1.4.1 (2021-12-25)
InputMethod: ReidlineInputMethod with Reline 0.3.1
RUBY_PLATFORM: x86_64-darwin21
LANG env: en_US.UTF-8
East Asian Ambiguous Width: 1
Terminal Emulator
I am using iTerm2 Build 3.4.14 which is configured to use xterm-256color.
I tested this using macOS's terminal app and the home and end keys also do not work there. I also retested irb under Ruby 3.0.3 to double-check that the home and end keys work properly which they do.
I managed to fix this by mapping Home and End keys in my iTerm2 profile key mappings to the hex codes 0x01 and 0x05 respectively. These hex codes map to Ctrl+A and Ctrl+E which in an iTerm2 session, function as Home (go to beginning of line) and End (go to end of line) and work as expected in irb. From my profile key mapping settings:
I think this may be a problem in reline, introduced in reline v0.2.7.
I switched to Ruby 3.0 with reline 0.2.0 and the problem went away. Then I tried various versions of reline and the problem first shows up in reline 0.2.7.
Digging further, it appears that the problem surfaced when default key bindings started using set_default_key_bindings_terminfo instead of set_default_key_bindings_comprehensive_list.
I added this line to the set_default_key_bindings_terminfo method in Reline::ANSI:
puts"MAPPING #{key.inspect} TO #{func}"
and it produced this:
MAPPING [27, 79, 72] TO ed_move_to_beg
MAPPING [27, 79, 70] TO ed_move_to_end
MAPPING [27, 79, 65] TO ed_prev_history
MAPPING [27, 79, 66] TO ed_next_history
MAPPING [27, 79, 67] TO ed_next_char
MAPPING [27, 79, 68] TO ed_prev_char
MAPPING [27, 91, 65] TO ed_prev_history
MAPPING [27, 91, 66] TO ed_next_history
MAPPING [27, 91, 67] TO ed_next_char
MAPPING [27, 91, 68] TO ed_prev_char
Those codes for Home and End don't match what's actually getting sent. But how could the term info be wrong? All other apps including bash and vim and you name it work totally fine in iTerm2, so I don't understand.
Also, it appears reline didn't even attempt to map the delete key...
I think this may be a problem in reline, introduced in reline v0.2.7.
I switched to Ruby 3.0 with reline 0.2.0 and the problem went away. Then I tried various versions of reline and the problem first shows up in reline 0.2.7.
Digging further, it appears that the problem surfaced when default key bindings started using set_default_key_bindings_terminfo instead of set_default_key_bindings_comprehensive_list.
I have this problem too, and I have tried to test with different versions of reline by your inspiration, and I found reline reline 74a7ffa is the first version have this problem.
I'm using Arch Linux with zsh.
In trying to understand terminfo better, I looked at the output of infocmp xterm -1 | grep home and noticed khome and home:
home=\E[H,
khome=\EOH,
khome is what should be received from the terminal when the home key is pressed
home is what could be sent to the terminal to tell it to move the cursor to the home position (upper left)
So the mapping in set_default_key_bindings_terminfo actually looks correct, since it is mapping khome == "\eOH" == [27, 79, 72] to :ed_move_to_beg.
Which means the problem seems to be on the input side of things. When I press the home key it is sending "\e[H" == [27, 91, 72]; why isn't it sending "\eOH"?
Update: I did some more research and discovered that (with xterm at least) there are two modes, normal and application. It is correct to send "\e[H" when in normal mode and "\eOH" when in application mode. And iTerm2 does switch to sending "\eOH" when I put it in application mode (e.g., by running tput smkx).
Here are a couple links I found helpful in understanding normal mode vs application mode:
I did a bunch of testing and I am convinced that iTerm2 is sending the wrong escape sequence for Home and End I believe iTerm2 is sending the correct sequences for everything except Insert.
Update: The main problem with Home and End is that the latest version of Reline only maps the application mode codes (SS3 == escape + O) not normal mode codes (CSI == escape + [), but it doesn't put the terminal into application mode.
The main problem with Delete, PgUp, and PgDown is that Reline is not mapping them to anything.
So here are all the issues and workarounds / solutions I've come up with:
Home key (khome)
Problem: Reline only recognizes \eOH not \e[H.
Workaround 1: Use Key Mappings to force iTerm2 to always map Home to \EOH
(Probably not a good idea)
Workaround 2: Force terminal into application mode when running IRB (and return to normal mode after)
See ~/.irbrc code block below
Solution 1: Fix Reline to put terminal into application mode (and return to normal mode after)
Problem: Reline doesn't map it to anything (although somehow it works on Linux)
Update: I believe the reason I wasn't seeing the problem on Linux is because reline was failing to load ncurses so it wasn't even using Reline::ANSI; see my comment here; anyway, now that I have ncurses loading I am also able to reproduce all these problems on Linux
Solution: Update Reline code to map 'kdch1' to :key_delete
For those that are impatient till reline#434 and reline#433 lands and makes it upstream to "irb". The quick & dirty fix for local installation is to apply patches against "ansi.rb" file (located at /<installation path to CRuby>/lib/ruby/3.1.0/reline/ansi.rb).
For those who would prefer to do the above patches at runtime, for macOS/iTerm2, add this code to "~/.irbrc":
require"reline/ansi"ifdefined?(Reline::ANSI::CAPNAME_KEY_BINDINGS)# make sure you're using an affected version# Fix insert, delete, pgup, and pgdown.Reline::ANSI::CAPNAME_KEY_BINDINGS.merge!({"kich1"=>:ed_ignore,"kdch1"=>:key_delete,"kpp"=>:ed_ignore,"knp"=>:ed_ignore})Reline::ANSI.singleton_class.prepend(Module.newdodefset_default_key_bindings(config)# Fix home and end.set_default_key_bindings_comprehensive_list(config)# Fix iTerm2 insert.key=[239,157,134]func=:ed_ignoreconfig.add_default_key_binding_by_keymap(:emacs,key,func)config.add_default_key_binding_by_keymap(:vi_insert,key,func)config.add_default_key_binding_by_keymap(:vi_command,key,func)# The rest of the behavior.superendend)end
No switch to application mode needed, and no iTerm2 rebinding.
Reacted by Aleksandrs Ļedovskis, Keith Wedinger, Phillip Hellewell, TerribleUsername, Skplunkerin, Frog Chen, Mai-Lapyst, Shubh A Chudasama, Joel Sugarman, neon and 9 more
Reacted by Simon Courtois, Oleg Grigoriev, Ondřej Želazko, Nick Stanish, Olly Headey, sergio-opslevel, Eric L. Truitte, MBA, Cyril Duchon-Doris and Sylvain
Apologies for adding a (potentially) meaningless comment to this thread, but @BrianHawley 's fix seems to work for me. It's resolved a long-standing issue with irb - I'm using Arch Linux, but I've triple-checked my system config (/etc/inputrc etc.) compared to Ubuntu, and couldn't see a difference in the terminal's behaviour. Home/End/Delete etc. didn't work for me, even before reline 0.2.0, and hasn't worked since Ruby 2.6, when I started learning Ruby. I get the same character patterns as this comment from @sshock
@neonn I think adding your experience is helpful and a good reminder to the maintainers of irb and reline that we still have people needing this to be fixed.
I've been waiting patiently for these fixes to be merged in (the last one is still DRAFT, but the first two are tiny and have been ready to go for 9 months):
Activity
jkwuc89 commentedon Jan 12, 2022
I tested this using macOS's terminal app and the home and end keys also do not work there. I also retested
irbunder Ruby 3.0.3 to double-check that the home and end keys work properly which they do.jkwuc89 commentedon Jan 12, 2022
I also tested this in a terminal on Ubuntu 20.04.3 LTS and the issue does not occur there.
jkwuc89 commentedon Jan 12, 2022
I managed to fix this by mapping Home and End keys in my iTerm2 profile key mappings to the hex codes 0x01 and 0x05 respectively. These hex codes map to Ctrl+A and Ctrl+E which in an iTerm2 session, function as Home (go to beginning of line) and End (go to end of line) and work as expected in irb. From my profile key mapping settings:
aycabta commentedon Jan 23, 2022
Would you try to run the following command and press Home/End key? You can exit with Ctrl+c.
Please copy the result.
jkwuc89 commentedon Jan 24, 2022
jkwuc89 commentedon Jan 24, 2022
I am seeing a similar issue with the Delete key. Output inside irb:

ruby -r reline -e 'while (c = Reline::IOGate.getc); pp c; end'shows the following for the Delete key.sshock commentedon Mar 5, 2022
I am having the same problem with Home, End, and Delete keys not working in iTerm2 on macOS and it is a major pain point for me.
Here's the output from
ruby -r reline -e 'while (c = Reline::IOGate.getc); pp c; end'for each of these:(Home):
(End):
(Delete):
(Side note: I believe @jkwuc89 's response for Home and End resulted in just a 1 and a 5 because he had already re-mapped those to Ctrl+A and Ctrl+E.)
Here are some more problematic keys that cause weird things to show up:
(Insert on Mac):
(Insert on PC):
(PgUp on Mac and PC):
(PgDn on Mac and PC):
sshock commentedon Mar 6, 2022
I think this may be a problem in reline, introduced in reline v0.2.7.
I switched to Ruby 3.0 with reline 0.2.0 and the problem went away. Then I tried various versions of reline and the problem first shows up in reline 0.2.7.
Digging further, it appears that the problem surfaced when default key bindings started using
set_default_key_bindings_terminfoinstead ofset_default_key_bindings_comprehensive_list.sshock commentedon Mar 6, 2022
I added this line to the
set_default_key_bindings_terminfomethod inReline::ANSI:and it produced this:
Those codes for Home and End don't match what's actually getting sent. But how could the term info be wrong? All other apps including bash and vim and you name it work totally fine in iTerm2, so I don't understand.
Also, it appears reline didn't even attempt to map the delete key...
jitingcn commentedon Mar 6, 2022
I have this problem too, and I have tried to test with different versions of reline by your inspiration, and I found reline reline 74a7ffa is the first version have this problem.
I'm using Arch Linux with zsh.
sshock commentedon Mar 6, 2022
In trying to understand terminfo better, I looked at the output of
infocmp xterm -1 | grep homeand noticedkhomeandhome:khomeis what should be received from the terminal when the home key is pressedhomeis what could be sent to the terminal to tell it to move the cursor to the home position (upper left)So the mapping in
set_default_key_bindings_terminfoactually looks correct, since it is mapping khome == "\eOH" == [27, 79, 72] to:ed_move_to_beg.Which means the problem seems to be on the input side of things. When I press the home key it is sending "\e[H" == [27, 91, 72]; why isn't it sending "\eOH"?
Update: I did some more research and discovered that (with xterm at least) there are two modes, normal and application. It is correct to send "\e[H" when in normal mode and "\eOH" when in application mode. And iTerm2 does switch to sending "\eOH" when I put it in application mode (e.g., by running
tput smkx).Here are a couple links I found helpful in understanding normal mode vs application mode:
sshock commentedon Mar 6, 2022
I did a bunch of testing and
I am convinced that iTerm2 is sending the wrong escape sequence for Home and EndI believe iTerm2 is sending the correct sequences for everything except Insert.Update: The main problem with Home and End is that the latest version of Reline only maps the application mode codes (SS3 == escape +
O) not normal mode codes (CSI == escape +[), but it doesn't put the terminal into application mode.The main problem with Delete, PgUp, and PgDown is that Reline is not mapping them to anything.
So here are all the issues and workarounds / solutions I've come up with:
Home key (khome)
\eOHnot\e[H.\EOHEnd key (kend)
\eOFnot\E[F.\EOFDelete key (kdch1 )
'kdch1'to:key_deleteInsert key (kich1)
\E[2~'kich1'to:ed_ignorePgUp key (kpp)
'kpp'to:ed_ignorePgDn key (knp)
'knp'to:ed_ignoreHere's a screenshot showing Home, End, and Insert key mappings changed in iTerm2 (not recommended, except for Insert key):
Here's what I added to ~/.irbrc to make it switch the terminal into application mode:
Here's a screenshot showing how to fix the Delete key in Reline, and also how to prevent Insert, PgUp, and PgDn from printing out nasties:
Always set default key bindings
Always set default key bindings
Always set default key bindings
aleksandrs-ledovskis commentedon Apr 20, 2022
Great investigation @sshock!
For those that are impatient till reline#434 and reline#433 lands and makes it upstream to "irb". The quick & dirty fix for local installation is to apply patches against "ansi.rb" file (located at
/<installation path to CRuby>/lib/ruby/3.1.0/reline/ansi.rb).Always set default key bindings
BrianHawley commentedon May 19, 2022
For those who would prefer to do the above patches at runtime, for macOS/iTerm2, add this code to "~/.irbrc":
No switch to application mode needed, and no iTerm2 rebinding.
madblobfish commentedon Jun 2, 2022
I discovered the following workaround for my setup (using archlinux, kitty and fish):
IRB.conf[:USE_MULTILINE] = falsein~/.irbrcsshock commentedon Sep 18, 2022
I discovered a new workaround that is relatively simple and fixes all keys; just modify
~/.inputrcto contain the following:neonn commentedon Dec 5, 2022
Apologies for adding a (potentially) meaningless comment to this thread, but @BrianHawley 's fix seems to work for me. It's resolved a long-standing issue with
irb- I'm using Arch Linux, but I've triple-checked my system config (/etc/inputrcetc.) compared to Ubuntu, and couldn't see a difference in the terminal's behaviour. Home/End/Delete etc. didn't work for me, even beforereline0.2.0, and hasn't worked since Ruby 2.6, when I started learning Ruby. I get the same character patterns as this comment from @sshocksshock commentedon Dec 6, 2022
@neonn I think adding your experience is helpful and a good reminder to the maintainers of irb and reline that we still have people needing this to be fixed.
I've been waiting patiently for these fixes to be merged in (the last one is still DRAFT, but the first two are tiny and have been ready to go for 9 months):
DRAFT - Fix Various Home / End key binding issues reline#462rgaufman commentedon Feb 4, 2023
The workarounds work, but any permanent solution?
sshock commentedon Feb 5, 2023
@rgaufman the delete key is fixed now, but we need to get one of these (preferably both) across the finish line to fix Home and End:
kendofriendo commentedon Mar 5, 2023
That also breaks command completion suggestions though while BrianHawley's solution doesn't.
Enter and leave keyboard transmit mode
st0012 commentedon Jul 19, 2023
I think this has been addressed by ruby/reline#569? cc @tompng