Skip to content

Commit

Permalink
bind: work around broken "cmd_xmap" after switching the editing mode
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed May 19, 2021
1 parent e55e3df commit 909f461
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 36 deletions.
2 changes: 2 additions & 0 deletions ble.pp
Expand Up @@ -184,6 +184,8 @@ function ble/base/initialize-version-information {
#------------------------------------------------------------------------------
# check environment

function ble/util/print { builtin printf '%s\n' "$1"; }

# ble/bin

## 関数 ble/bin/.default-utility-path commands...
Expand Down
89 changes: 58 additions & 31 deletions lib/init-bind.sh
Expand Up @@ -7,18 +7,16 @@
#

function ble/init:bind/append {
local xarg="\"$1\":ble-decode/.hook $2; builtin eval \"\$_ble_decode_bind_hook\""
local rarg=$1 condition=$3
echo "$condition${condition:+ && }builtin bind -x '${xarg//$apos/$APOS}'" >> "$fbind1"
echo "$condition${condition:+ && }builtin bind -r '${rarg//$apos/$APOS}'" >> "$fbind2"
local xarg="\"$1\":ble-decode/.hook $2; builtin eval -- \"\$_ble_decode_bind_hook\""
local rarg=$1 condition=$3${3:+' && '}
ble/util/print "${condition}builtin bind -x '${xarg//$apos/$APOS}'" >> "$fbind1"
ble/util/print "${condition}builtin bind -r '${rarg//$apos/$APOS}'" >> "$fbind2"
}
function ble/init:bind/bind-s {
local sarg="$1"
echo "builtin bind '${sarg//$apos/$APOS}'" >> "$fbind1"
}
function ble/init:bind/bind-r {
local rarg="$1"
echo "builtin bind -r '${rarg//$apos/$APOS}'" >> "$fbind2"
function ble/init:bind/append-macro {
local kseq1=$1 kseq2=$2 condition=$3${3:+' && '}
local sarg="\"$kseq1\":\"$kseq2\"" rarg=$kseq1
ble/util/print "${condition}builtin bind '${sarg//$apos/$APOS}'" >> "$fbind1"
ble/util/print "${condition}builtin bind -r '${rarg//$apos/$APOS}'" >> "$fbind2"
}

function ble/init:bind/generate-binder {
Expand All @@ -31,6 +29,8 @@ function ble/init:bind/generate-binder {
: >| "$fbind2"

local apos=\' APOS="'\\''"
local altdqs24='\xC0\x98'
local altdqs27='\xC0\x9B'

# ※bash-4.3 以降は bind -x の振る舞いがこれまでと色々と違う様だ
# 何より 3 byte 以上の物にも bind できる様になった点が大きい (が ble.sh では使っていない)
Expand All @@ -40,9 +40,10 @@ function ble/init:bind/generate-binder {
# bash_execute_unix_command: cannot find keymap for command
# になってしまう。"C-@ *" に全て割り当てても駄目である。
# bind '"\C-@":""' は使える様なので、UTF-8 の別表現に翻訳してしまう。
local esc00=$((_ble_bash>=40300))
local esc00=$((40300<=_ble_bash&&_ble_bash<50000))

# * C-x (24) に単体で直接 bind -x するとクラッシュする問題。
# #D0017 #D0018 #D0057 #D0122 #D0148 #D0391 #D0583 #D1478
#
# [症状]
# bash-4.3 を除く bash-3.0 ~ bash-4.4 の全てで、set -o emacs で問題が生じる。
Expand All @@ -51,15 +52,38 @@ function ble/init:bind/generate-binder {
# それ以外の bash では、何秒かしてクラッシュする。
# bash-5.0 では修正されたので対策は不要になった (#D1163)
#
# [対処法1]
# [対処法1] "C-x ?" 全束縛 ... bash-3.0..4.2 で使用
#
# C-x には直接 bind せずに 2 文字の組み合わせで bind -x '"\C-x?": ...' とする。
#
# [対処法2] 却下 #D0582
# * bash-3.0..4.2: これをすると vi に切り替えた時に後遺症が残る。
# cmd_xmap[24] に submap が追加される事により、\C-x に対して \C-x\C-x の
# コマンドが実行される様になる。その対策として直接 "\C-x?" に対して bind
# -x するのではなくて、"\C-x?" をマクロで UTF-8 代替表現に置き換えて受信
# する。 (#D1478)
#
# [対処法2] 却下 #D0583
# bind -s '"\C-x": "\xC0\x98"' のようにする。
# クラッシュはしなくなるが、謎の遅延が残る。
# 遅延をなくすには 対処法1 を実行するしかない。
#
local bind18XX=$((_ble_bash<40300||40400<=_ble_bash&&_ble_bash<50000))
# [対処法3] 単一 C-x (with \C-x\C-x shadow) ... bash-4.4 で使用 (#D1478)
#
# 一旦 bind -x '"\C-x\C-x":hook 24' としてから bind -r '\C-x\C-x' で削除す
# る。この後で bind -x '"\C-x":...' で timeout すると "\C-x\C-x" のコマンド
# が実行される。
#
# * bash-3.0..4.2 で \C-x\C-x に一度でも bind すると C-x で timeout しなく
# なるので、この対策を実行するのは emacs keymap のみにする。
#
local bind18XX=0
if ((40400<=_ble_bash&&_ble_bash<50000)); then
# Insert a dummy entry in "cmd_xmap"
ble/util/print "[[ -o emacs ]] && bind 'set keyseq-timeout 1'" >> "$fbind1"
fbind2=$fbind1 ble/init:bind/append '\C-x\C-x' 24 '[[ -o emacs ]]'
elif ((_ble_bash<40300)); then
bind18XX=1
fi

# ESC について
#
Expand Down Expand Up @@ -129,8 +153,7 @@ function ble/init:bind/generate-binder {
# C-@
if ((esc00)); then
# ENCODING: UTF-8 2-byte code of 0 (UTF-8依存)
ble/init:bind/bind-s '"\C-@":"\xC0\x80"'
ble/init:bind/bind-r '\C-@'
ble/init:bind/append-macro '\C-@' '\xC0\x80'
else
ble/init:bind/append "$ret" "$i"
fi
Expand All @@ -147,12 +170,10 @@ function ble/init:bind/generate-binder {
ble/init:bind/append "$ret" "$i"
elif ((esc1B==2)); then
# ENCODING: UTF-8
ble/init:bind/bind-s '"\e":"\xC0\x9B"'
ble/init:bind/bind-r '\e'
ble/init:bind/append-macro '\e' "$altdqs27"
elif ((esc1B==3)); then
# ENCODING: UTF-8 (_ble_decode_IsolatedESC U+07FF)
ble/init:bind/bind-s '"\e":"\xDF\xBF"' # C-[
ble/init:bind/bind-r '\e'
ble/init:bind/append-macro '\e' '\xDF\xBF' # C-[
fi
else
# Note: Bash-5.0 では \C-\\ で bind すると変な事になる #D1162 #D1078
Expand All @@ -164,12 +185,20 @@ function ble/init:bind/generate-binder {
# ble/init:bind/append "\\C-@$ret" "0 $i"

# C-x *
((bind18XX)) && ble/init:bind/append "$ret" "24 $i" '[[ -o emacs ]]'
if ((bind18XX)); then
# emacs mode では "C-x ?" の組み合わせで登録する。
# Note: 普通に bind -x すると cmd_xmap の \C-x が曖昧になって vi 側の単一
# "C-x" が動かなくなるので、ここでは UTF-8 2B 表示を通して受信する。
if ((i==24)); then
ble/init:bind/append-macro "\C-x$ret" "$altdqs24$altdqs24" '[[ -o emacs ]]'
else
ble/init:bind/append-macro "\C-x$ret" "$altdqs24$ret" '[[ -o emacs ]]'
fi
fi

# ESC *
if ((esc1B==3)); then
ble/init:bind/bind-s '"\e'"$ret"'":"\xC0\x9B'"$ret"'"'
ble/init:bind/bind-r '\e'"$ret"
ble/init:bind/append-macro '\e'"$ret" "$altdqs27$ret"
else
if ((esc1B==1)); then
# ESC [
Expand All @@ -179,11 +208,10 @@ function ble/init:bind/generate-binder {
# 受信した後で CSI を ESC [ に戻す。
# CSI = \u009B = utf8{\xC2\x9B} = utf8{\302\233}
# printf 'bind %q' '"\e[":"\302\233"' >> "$fbind1"
# echo "ble-bind -f 'CSI' '.ble-decode-char 27 91'" >> "$fbind1"
# echo "ble-bind -f 'CSI' '.CHARS 27 91'" >> "$fbind1"

# ENCODING: \xC0\x9B is 2-byte code of ESC (UTF-8依存)
ble/init:bind/bind-s '"\e[":"\xC0\x9B["'
ble/init:bind/bind-r '\e['
ble/init:bind/append-macro '\e[' "$altdqs27["
else
ble/init:bind/append "\\e$ret" "27 $i"
fi
Expand All @@ -192,10 +220,9 @@ function ble/init:bind/generate-binder {
# ESC ESC
if ((i==27&&esc1B1B)); then
# ESC ESC for bash-4.1
ble/init:bind/bind-s '"\e\e":"\e[^"'
echo "ble-bind -k 'ESC [ ^' __esc__" >> "$fbind1"
echo "ble-bind -f __esc__ '.ble-decode-char 27 27'" >> "$fbind1"
ble/init:bind/bind-r '\e\e'
ble/init:bind/append-macro '\e\e' '\e[^'
ble/util/print "ble-bind -k 'ESC [ ^' __esc__" >> "$fbind1"
ble/util/print "ble-bind -f __esc__ '.CHARS 27 27'" >> "$fbind1"
fi
fi
done
Expand Down
10 changes: 5 additions & 5 deletions src/decode.sh
Expand Up @@ -1182,7 +1182,7 @@ function ble-decode-key/dump {
echo "ble-bind$kmapopt -c '${knames//$q/$Q}' ${cmd#ble/widget/.SHELL_COMMAND }" ;;
('ble/widget/.EDIT_COMMAND '*)
echo "ble-bind$kmapopt -x '${knames//$q/$Q}' ${cmd#ble/widget/.EDIT_COMMAND }" ;;
('ble/widget/.ble-decode-char '*)
('ble/widget/.CHARS '*)
local ret; ble/util/chars2keyseq ${cmd#*' '}
echo "ble-bind$kmapopt -s '${knames//$q/$Q}' '${ret//$q/$Q}'" ;;
('ble/widget/'*)
Expand Down Expand Up @@ -1883,7 +1883,7 @@ function ble-bind {
command="ble/widget/.SHELL_COMMAND '${command//$q/$Q}'" ;;
(s)
local ret; ble/util/keyseq2chars "$command"
command="ble/widget/.ble-decode-char ${ret[*]}" ;;
command="ble/widget/.CHARS ${ret[*]}" ;;
('@') ;; # 直接実行
(*)
echo "error: unsupported binding type \`-$c'." 1>&2
Expand Down Expand Up @@ -1918,10 +1918,10 @@ function ble-bind {

# **** ESC ESC **** @decode.bind.esc2

## 関数 ble/widget/.ble-decode-char ...
## 関数 ble/widget/.CHARS ...
## - lib/init-bind.sh で設定する bind で使用する。
## - bind '"keyseq":"macro"' の束縛に使用する。
function ble/widget/.ble-decode-char {
function ble/widget/.CHARS {
ble-decode-char "$@"
}

Expand Down Expand Up @@ -2702,7 +2702,7 @@ function ble/builtin/bind/option:- {
# keyboard macro
value=${value#\"} value=${value%\"}
local ret chars; ble/util/keyseq2chars "$value"; chars=("${ret[@]}")
local command="ble/widget/.ble-decode-char ${chars[*]}"
local command="ble/widget/.CHARS ${chars[*]}"
ble-decode-key/bind "${keys[*]}" "$command"
elif [[ $value ]]; then
if local ret; ble/builtin/bind/rlfunc2widget "$kmap" "$value"; then
Expand Down

0 comments on commit 909f461

Please sign in to comment.