Always set ANSI CSI keybindings for Home, End, and Arrow.#569
Always set ANSI CSI keybindings for Home, End, and Arrow.#569tompng merged 1 commit intoruby:masterfrom
Conversation
| [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→, extended entry | ||
| [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←, extended entry | ||
| [27, 91, 49, 59, 51, 67] => :em_next_word, # Meta+→, extended entry | ||
| [27, 91, 49, 59, 51, 68] => :ed_prev_word, # Meta+←, extended entry |
There was a problem hiding this comment.
"\e[1;5C", "\e[1;5D", "\e[1;3C", "\e[1;3D" will be bound in set_default_key_bindings_ansi_cursor
| [27, 27, 91, 67] => :em_next_word, # Option+→, extended entry | ||
| [27, 27, 91, 68] => :ed_prev_word, # Option+←, extended entry | ||
| [195, 166] => :em_next_word, # Option+f | ||
| [195, 162] => :ed_prev_word, # Option+b |
There was a problem hiding this comment.
[195, 166] and [195,162] are unicode bytes for æ and â. It's not an escape sequence.
In mac, option+f option+b will insert ƒ ∫ in any textarea and also in iTerm2, but we don't want to add 'ƒ'.bytes '∫'.bytes to this list. Same for æ and â.
| # Escape sequences that omit the move distance and are set to defaults | ||
| # value 1 may be sometimes sent by pressing the arrow-key. | ||
| when 'cuu', 'cud', 'cuf', 'cub' | ||
| [ key_code.sub(/%p1%d/, '').bytes, key_binding ] |
There was a problem hiding this comment.
# searched cuu from terminfo
cuu=\E[%p1%dA
cuu=\233%p1%dA
cuu=\Ep-%p1%d;
cuu=\E&a-%p1%dR
cuu=\E[%p1%dA$<5>
cuu=\E[%p1%dA$<30>
cuu=\037up %p1%d\r
cuu=\035up %p1%d;
these are not for input sequence. It's for output sequence like \e[42A = move cursor up 42 rows.
This pattern does not match to \e[A (UP) nor \e[1;2A (UP+SHIFT).
We need to explicitly bind "\e[A", not irrelevant_value.gsub(replace_it, to_match_CSI_A)
| bindings = [["\e[#{char}", default_func]] # CSI + char | ||
| if modifiers[:ctrl] | ||
| # CSI + ctrl_key_modifier + char | ||
| bindings << ["\e[1;5#{char}", modifiers[:ctrl]] |
There was a problem hiding this comment.
In https://mdfs.net/Docs/Comp/Comms/ANSIKeys, it says "\e[1;5D" and also "\e[5D" is valid as Ctrl+Left.
Although, I think we only need 1;5 style because set_default_key_bindings_comprehensive_list only had \e[1;5D, emacs and readline only supports \e[1;5D style.
st0012
left a comment
There was a problem hiding this comment.
Generally looks good and the description/comments are easy to follow 👍
2 questions:
- Since this PR sets new default bindings, I think it's an enhancement?
- Can you provide a few manual test steps to check the behaviour changes? I can perform them on
Terminal.app,iTerm2andVS Code Terminal.
|
To check the input sequence, use |
|
LGTM |
I can confirm these changes with my testing 👍
This is a very useful snippet. Can you add it to the |

Fixes HOME key, END key, Meta + Arrow key problem in some terminal emulator.
ANSI cursor sequence
Most terminals are vt100 compatible. In vt100 normal mode, ANSI cursor sequence
"\e[A", "\e[B", "\e[C", "\e[D"will be sent on arrow key press.("Cursor Control" section of https://vt100.net/docs/vt100-ug/chapter3.html, "Minimum requirements for VT100 emulation" section of https://www.real-world-systems.com/docs/ANSIcode.html)
These arrow key sequence are normally not written in terminfo. This pull request make Reline bind these cursor sequences as default.
HOME
\e[Hand END\e[Fkeys are also categorized as cursor sequence. You can check this by setting Cursor Key Mode (DECCKM). HOME/END key will change the behavior just like arrow key does.Modifiers
In https://mdfs.net/Docs/Comp/Comms/ANSIKeys, it says that terminal emulator will add a modifier value like
"\e[1;3A"for Meta+Up,"\e[1;5A"for Ctrl+Up. Some terminal emulator uses"\e\e[A"for Meta+Up instead of modifier value.(
\ebis handled byReline::KeyStroke#compress_meta_key)This pull request also bind these arrow + modifier key sequences.
Reduce comprehensive list
Some bytes in
set_default_key_bindings_comprehensive_listwill be registered as default. I've removed them from comprehensive_list.