emacs 模式下的 KSH 键映射:ctrl + 方向键

emacs 模式下的 KSH 键映射:ctrl + 方向键

我是 KSH 的新手,必须在工作中使用它。版本是:

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

在 RHEL 上。我以前使用过 tcsh 并使用它的 bindkey 工具为我提供了一些很好的命令行操作快捷方式。我在 KSH 中找到了“keybind”函数的代码,并用它来使 home、end 和 delete 按我想要的方式工作:

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

我实际上不确定为什么我有两个对应于“End”的内容,但我确实如此。无论如何,棘手的部分是我想要 ctrl+左/右箭头跳过一个单词,而不是使用 Mf 或 Mb。当我尝试获取 ctrl-left arrow 的代码时,它显示:

^[[1;5D

但我似乎无法让它在 keybind 命令中工作。由于分号的存在,它看起来几乎像是一个复合按键。我之前也没有看到过这个问题,因此我们将不胜感激。

谢谢,马特

答案1

ksh 手册页中记录的 KEYBD 陷阱被调用以处理以转义开头的传入字符序列。这个序列的结尾没有描述,但似乎;会结束它。

假设您的按键绑定功能如下所示文章,那么您的绑定就会失败,因为首先调用陷阱代码 for \e[1;,然后调用 for5D

一种解决方案是更改陷阱代码以记住初始序列,并在以后使用它,如下所示:

# 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'

相关内容