I'm new to KSH, have to use it at my job. Version is:

sh (AT&T Research) 93u+ 2012-08-01

on RHEL. I previously used tcsh and used its bindkey facility to give me some good command-line manipulation shortcuts. I found the code for a "keybind" function in KSH, and used that to make home, end, and delete work the way I want:

keybind $'\eOH'  $'\001'
keybind $'\eOF'  $'\005'
keybind $'\e[F'  $'\005'
keybind $'\e[3~'  $'\004'

I'm actally not sure why I have two that correspond to "End" but I do. In any case, the tricky part is that I want ctrl+left/right arrow to skip a word, instead of using M-f or M-b. When I try to get the code for ctrl-left arrow, it shows:


but I can't seem to get this to work in the keybind command. It seems almost like a compound keystroke due to the semicolon. I also haven't seen this question asked before so any help would be appreciated.

Thanks, Matt

  • After several hours of searching the internet, this is the one and only place I've found that shows how to map a Delete key that sends \e[3~ to the Emacs delete-char-forward command.
    – dpw
    Feb 25 '20 at 1:32

The KEYBD trap documented in the ksh man page is called for an incoming character sequence that begins with escape. The end of this sequence is not described, but it seems that ; will end it.

Assuming your keybind function is as given in this article, then your binding fails because the trap code is called first for \e[1;, then for 5 and D.

One solution is to change the trap code to remember the initial sequence, and use it later, as follows:

# original code from http://www.bolthole.com/solaris/ksh-oddthings.html
typeset -A Keytable
# trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD
function keybind # key action
    typeset key=$(print -f "%q" "$2")
    case $# in
    2)      Keytable[$1]=' .sh.edchar=${.sh.edmode}'"$key" ;;
    1)      unset Keytable[$1] ;;
    *)      print -u2 "Usage: $0 key [action]" ;;

# new function to handle ";" causing end of sequence
# https://unix.stackexchange.com/a/425980/119298
function myfn {
    typeset -S state
    case "$state${.sh.edchar}" in
    $'\e[1;')   state=${.sh.edchar}
                return ;;
    $'\e[1;5')  state="$state${.sh.edchar}"
                return ;;
    $'\e[1;5'?) state=
                .sh.edchar=$'\e[1;5'"${.sh.edchar}" ;;
    eval "${Keytable[${.sh.edchar}]}"

trap myfn KEYBD

keybind $'\e[1;5D' $'\eb'
keybind $'\e[1;5C' $'\ef'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.