Saturday, September 23, 2017

The .inputrc revisited

I've been talking about .inputrc once in a while since a few years:

Now I'm going to revisit it once more and I suspect I'll do it again in the future. But for now the goal is to hopefully provide a better example of more key bindings once a more correct and richer console keyboard configuration is available.

The first notice I would add about BASH key bindings is that it seems to be an exclusively per user configuration (~/.inputrc). That is, it seems that no global /etc/inputrc or /etc/bash/inputrc would work by default, at least under Solaris 11.3 GA. Thus, at first one have no option other than using a per user, local ~/.inputrc.

NOTE
In spite of BASH or READLINE being completely death about processing by default a global /etc/bash/inputrc, I can use an $include /etc/bash/inputrc directive inside an ~/.inputrc as a viable workaround, yet this would not provide partial overriding.

There's no sense in repeating what's explained at BASH(1) so I'll go straight to the example and, if necessary, present a few comments or justifications:

$ cat /etc/bash/inputrc_console_basics
 
$if mode=emacs
# Basic key bindings while under an emacs console terminal. 
# These bindings may be more easily remembered and accessed. 
# This is in spite of bind-tty-special-chars being partially OK.

# OK : forward-char
# OK : backward-char


# Ins
"\e[208z": overwrite-mode

# Del
"
\e[214z": delete-char

# Home
"
\e[210z": beginning-of-line

# End
"
\e[216z": end-of-line

# ^Right

"
\e[220z": forward-word

# ^Left
"
\e[221z": backward-word

# ^Bksp

"
\e[189z": backward-kill-word

# ^Del
"
\e[215z": kill-word

# ^Home
"
\e[211z": backward-kill-line

# ^End
"
\e[217z": kill-line

# ^Down

"
\e[222z": downcase-word

# ^Up
"
\e[223z": upcase-word

$endif



NOTE
One could consider replacing some or all of the *-word actions above by the corresponding shell-*-word ones, whenever possible. Or perhaps adding a few more actions to the keyboard layout, such as, Shift+Bksp, Shift+Del and so on... in order to gather all the options at the same time, if not too confusing.

The settings below also address the single-user run-state when the terminal gets dumb:

$ cat ~/.inputrc

# To keep sanity.
set bell-style none

# On generic x86-64 this kind of console seems the default.

$if term=sun-color
$include /etc/bash/inputrc_console_basics
$endif

# But while on single-user run-state the terminal gets dumb.
# By default only relates to root but that can be changed with:
# usermod -A +solaris.system.maintenance ...

$if term=dumb
$include /etc/bash/inputrc_console_basics
$endif
 
Why not take the opportunity and also do something to get slightly similar behavior while under an xterm terminal? Even if X isn't installed locally that might be useful while remotely administering from a system that does; typically an SSH session launched from a graphical terminal or yet via some software that emulates an xterm, such as PuTTY. For instance:

$ cat /etc/bash/inputrc_PuTTY_xterm_basics

$if mode=emacs

"\e[1~": beginning-of-line
"\e[4~": end-of-line

"\e[3~": delete-char
"\e[2~": overwrite-mode

"\eOC": forward-word
"\eOD": backward-word

"\eOA": upcase-word
"\eOB": downcase-word


$endif


NOTE
The escape sequences above are generated by the same key combinations (as available under a default XKB configuration), corresponding to those indicated in comments on the sample input_console_basics above.

Then it would suffice to add an extra inclusion to the above .inputrc sample:

$ cat ~/.inputrc

...

# Trying to mimic some console settings under a PuTTY xterm:
# This assumes an out-of-the-box XKB configuration...

$if term=xterm
$include /etc/bash/inputrc_PuTTY_xterm_basics
$endif
  
NOTE
I'm assuming a basic (out-of-the-box) xterm emulation both from PuTTY or gnome-terminal.  That is, I'm not considering enhanced settings of the TERM enviroment variables such as xterm-256color or putty-256color which would required me to add additional if term= statements to my .inputrc file.
For a gnome-terminal emulated xterm I could have the following differences:

$ cat /etc/bash/inputrc_xterm_basics

$if mode=emacs

"\e[1~": beginning-of-line
"\e[4~": end-of-line

"\e[3~": delete-char
"\e[2~": overwrite-mode

"\e[1;5C": forward-word
"\e[1;5D": backward-word

"\e[1;5A": upcase-word
"\e[1;5B": downcase-word


$endif
   
NOTE
To find out the proper bindings on each case, once at a certain terminal emulator, I must hit ^V followed by the key combination I wish to detect the associated escape sequence.