1

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:

^[[1;5D

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

1

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]" ;;
    esac
}

# 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}
                .sh.edchar=
                return ;;
    $'\e[1;5')  state="$state${.sh.edchar}"
                .sh.edchar=
                return ;;
    $'\e[1;5'?) state=
                .sh.edchar=$'\e[1;5'"${.sh.edchar}" ;;
    esac
    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.