Skip to content

Commit

Permalink
rlfunc: support vi word operations in "emacs" keymap
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Jul 12, 2021
1 parent 899c114 commit 21d636a
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 36 deletions.
3 changes: 2 additions & 1 deletion blerc
Expand Up @@ -35,7 +35,8 @@

## The following setting specifies the editor used by ble.sh. This is used for
## the widget edit-and-execute (C-x C-e) and editor for a large amount of
## command line texts. Possible values are e.g. "vim", "emacs -nw" or "nano".
## command line texts. Possible values include, for example, "vim", "emacs
## -nw" and "nano".

#bleopt editor=vim

Expand Down
6 changes: 6 additions & 0 deletions keymap/emacs.sh
Expand Up @@ -11,6 +11,12 @@ function ble-edit/bind/load-editing-mode:emacs { :; }
# 2021-01-25 force update (change mapping of C-w and M-w)
# 2021-04-26 force update (rename ble/decode/keymap#.register)

# vi functions referenced from core-decode.emacs-rlfunc.txt
ble/util/autoload "$_ble_base/keymap/vi.sh" \
ble/widget/vi-rlfunc/{prev,end,next}-word \
ble/widget/vi-command/{forward,backward}-{v,u}word \
ble/widget/vi-command/forward-{v,u}word-end

#------------------------------------------------------------------------------

_ble_keymap_emacs_white_list=(
Expand Down
9 changes: 8 additions & 1 deletion keymap/vi.sh
Expand Up @@ -643,7 +643,7 @@ function ble/widget/vi_nmap/.insert-mode {
_ble_keymap_vi_insert_overwrite=$overwrite
_ble_keymap_vi_single_command=
_ble_keymap_vi_single_command_overwrite=
_ble_keymap_vi_search_matched=
ble/keymap:vi/search/clear-matched
ble/decode/keymap/pop
ble/keymap:vi/update-mode-name

Expand Down Expand Up @@ -7651,6 +7651,12 @@ function ble/widget/vi_imap/__attach__ {
ble/keymap:vi/update-mode-name
return 0
}
function ble/widget/vi_imap/__detach__ {
ble/edit/info/default clear
ble/keymap:vi/clear-arg
ble/keymap:vi/search/clear-matched
return 0
}
function ble/widget/vi_imap/accept-single-line-or {
if ble-edit/is-single-complete-line; then
ble/keymap:vi/imap-repeat/reset
Expand Down Expand Up @@ -7883,6 +7889,7 @@ function ble-decode/keymap:vi_imap/define {
# vi bindings

ble-bind -f __attach__ vi_imap/__attach__
ble-bind -f __detach__ vi_imap/__detach__
ble-bind -f __default__ vi_imap/__default__
ble-bind -f __before_widget__ vi_imap/__before_widget__
ble-bind -f __line_limit__ __line_limit__
Expand Down
4 changes: 2 additions & 2 deletions lib/core-complete.sh
Expand Up @@ -2542,10 +2542,10 @@ function ble/complete/progcomp/.compgen {
}
ble/function#suppress-stderr _filedir 2>/dev/null

# https://github.com/scop/bash-completion/issues/509 (fixed in bash-completion 2.11)
# https://github.com/scop/bash-completion/issues/509 (fixed in bash-completion 2.12)
ble/function#suppress-stderr _find 2>/dev/null

# https://github.com/scop/bash-completion/pull/556 (fixed in bash-completion 2.11)
# https://github.com/scop/bash-completion/pull/556 (fixed in bash-completion 2.12)
ble/function#suppress-stderr _scp_remote_files 2>/dev/null
fi
fi
Expand Down
30 changes: 15 additions & 15 deletions lib/core-decode.emacs-rlfunc.txt
Expand Up @@ -70,7 +70,7 @@ magic-space magic-space
menu-complete menu-complete
menu-complete-backward menu-complete backward
next-history history-next
next-screen-line forward-graphical-line
next-screen-line @nomarked forward-graphical-line
non-incremental-forward-search-history history-nsearch-forward
non-incremental-forward-search-history-again history-nsearch-forward-again
non-incremental-reverse-search-history history-nsearch-backward
Expand Down Expand Up @@ -116,11 +116,21 @@ upcase-word upcase-eword
vi-append-eol -
vi-append-mode -
vi-arg-digit -
vi-bWord -
vi-prev-word vi-rlfunc/prev-word
vi-backward-word vi-command/backward-vword
vi-backward-bigword vi-command/backward-uword
vi-bword vi-command/backward-vword
vi-bWord vi-command/backward-uword
vi-end-word vi-rlfunc/end-word
vi-end-bigword vi-command/forward-uword-end
vi-eword vi-command/forward-vword-end
vi-eWord vi-command/forward-uword-end
vi-next-word vi-rlfunc/next-word
vi-forward-word vi-command/forward-vword
vi-forward-bigword vi-command/forward-uword
vi-fword vi-command/forward-vword
vi-fWord vi-command/forward-uword
vi-back-to-indent -
vi-backward-bigword -
vi-backward-word -
vi-bword -
vi-change-case -
vi-change-char -
vi-change-to -
Expand All @@ -129,27 +139,17 @@ vi-column -
vi-complete -
vi-delete -
vi-delete-to -
vi-eWord -
vi-editing-mode vi-editing-mode
vi-end-bigword -
vi-end-word -
vi-eof-maybe -
vi-eword -
vi-fWord -
vi-fetch-history -
vi-first-print -
vi-forward-bigword -
vi-forward-word -
vi-fword -
vi-goto-mark -
vi-insert-beg -
vi-insertion-mode -
vi-match -
vi-movement-mode -
vi-next-word -
vi-overstrike -
vi-overstrike-delete -
vi-prev-word -
vi-put -
vi-redo -
vi-replace -
Expand Down
30 changes: 15 additions & 15 deletions lib/core-decode.vi_imap-rlfunc.txt
Expand Up @@ -70,7 +70,7 @@ magic-space magic-space
menu-complete menu-complete
menu-complete-backward menu-complete backward
next-history history-next
next-screen-line forward-graphical-line
next-screen-line @nomarked forward-graphical-line
non-incremental-forward-search-history history-nsearch-forward
non-incremental-forward-search-history-again history-nsearch-forward-again
non-incremental-reverse-search-history history-nsearch-backward
Expand Down Expand Up @@ -116,11 +116,21 @@ upcase-word upcase-eword
vi-append-eol -
vi-append-mode -
vi-arg-digit -
vi-bWord -
vi-back-to-indent -
vi-backward-bigword -
vi-backward-word -
vi-bword -
vi-prev-word vi-rlfunc/prev-word
vi-backward-word vi-command/backward-vword
vi-backward-bigword vi-command/backward-uword
vi-bword vi-command/backward-vword
vi-bWord vi-command/backward-uword
vi-end-word vi-rlfunc/end-word
vi-end-bigword vi-command/forward-uword-end
vi-eword vi-command/forward-vword-end
vi-eWord vi-command/forward-uword-end
vi-next-word vi-rlfunc/next-word
vi-forward-word vi-command/forward-vword
vi-forward-bigword vi-command/forward-uword
vi-fword vi-command/forward-vword
vi-fWord vi-command/forward-uword
vi-change-case -
vi-change-char -
vi-change-to -
Expand All @@ -129,27 +139,17 @@ vi-column -
vi-complete -
vi-delete -
vi-delete-to -
vi-eWord -
vi-editing-mode nop
vi-end-bigword -
vi-end-word -
vi-eof-maybe -
vi-eword -
vi-fWord -
vi-fetch-history -
vi-first-print -
vi-forward-bigword -
vi-forward-word -
vi-fword -
vi-goto-mark -
vi-insert-beg -
vi-insertion-mode nop
vi-match -
vi-movement-mode vi_imap/normal-mode
vi-next-word -
vi-overstrike -
vi-overstrike-delete -
vi-prev-word -
vi-put -
vi-redo -
vi-replace vi_imap/overwrite-mode
Expand Down
1 change: 1 addition & 0 deletions lib/core-decode.vi_nmap-rlfunc.txt
Expand Up @@ -159,6 +159,7 @@ vi-search-again vi-rlfunc/search-again
vi-set-mark vi-command/set-mark
vi-subst vi-rlfunc/subst
vi-tilde-expand -
vi-undo vi_nmap/undo
vi-unix-word-rubout -
vi-yank-arg vi-rlfunc/yank-arg
vi-yank-pop -
Expand Down
2 changes: 2 additions & 0 deletions lib/init-cmap.sh
Expand Up @@ -31,6 +31,7 @@
# __before_widget__
# __after_widget__
# __attach__
# __detach__
#
# 修飾キー
#
Expand All @@ -50,6 +51,7 @@
# 2020-03-12 __line_limit__ を追加
# 2020-04-13 cmap キャッシュ生成バグ修正に伴う更新。
# 2020-04-29 cmap キャッシュ生成バグ修正に伴う更新 (2)
# 2021-07-12 __detach__ 追加

function ble/init:cmap/bind-single-csi {
ble-bind -k "ESC [ $1" "$2"
Expand Down
1 change: 1 addition & 0 deletions memo/ChangeLog.md
Expand Up @@ -62,6 +62,7 @@
- syntax: highlight quotes of the `\?` form `#D1584` 5076a03
- prompt: support a new backslash sequence `\g{...}` `#D1609` be31391
- complete: add a new option `bleopt complete_limit_auto_menu` `#D1618` 0000000
- rlfunc: support vi word operations in `emacs` keymap (requested by SolarAquarion) `#D1624` 0000000

## Changes

Expand Down
98 changes: 98 additions & 0 deletions note.txt
Expand Up @@ -4666,6 +4666,104 @@ bash_tips
Done (実装ログ)
-------------------------------------------------------------------------------

2021-07-12

* emacs モードで vi-bword 使う (requested by SolarAquarion) [#D1624]
https://github.com/akinomyoga/ble.sh/issues/125

調べると vi-bword vi-Bword があって、内部的にはそれぞれ vword uword として
いる。それなら edit.sh に既に定義されている vword, uword を代わりに呼び出し
たら良いのではないか、と考えたが、vword は定義されていない。実装を具体的に
観察すると単純に単語決定に使う文字集合を edit.sh に引き込めば良いという訳で
もない。

観察する限りでは別に emacs mode でこの vi-bword 等を呼び出しても特に問題は
生じない様にも見える。念の為どの変数を参照していてどの変数が emacs mode で
期待している値になっているのかについて確認する。

単語単位の移動は ble/widget/vi-command/forward-word.impl 等で実行されている。
特別な動作をするかどうかは渡された引数 flag で判定している。取り敢えず flag
が空だと仮定するとそのまま ble/widget/vi-command/exclusive-goto.impl
"$index" "$flag" "$reg" が呼び出される。そしてそのまま exclusive-range.impl
に渡される。ble/keymap:vi/needs-eol-fix "$dst" && ((dst--)) が呼び出されて、
移動して、 ble/keymap:vi/adjust-command-mode が呼び出さる。

* 最初の flag に関しては ble/keymap:vi/get-arg 経由で _ble_keymap_vi_reg の
値を読み取っている。これは get-arg を呼び出していれば clear されている筈。
一方で、set -o emacs 等を実行した時にちゃんとクリアされるだろうか。少なく
とも vi-command/accept-line の中では clear-arg が呼び出されている。

vi_imap の中にいる時にちゃんと clear されているのかというのは気になる。一
応 ble/widget/vi_nmap/.insert-mode を呼び出す時にはちゃんと
ble/keymap:vi/clear-arg が事前に呼び出される様に書いてある様である (見落
としはあるかもしれないが)。

emacs-editing-mode 経由で切り替えた時にちゃんと arg が clear されるのかど
うか。見た所は全く考慮に入れていない様に見える。

a reject: keymap に attach する時に clear する? 然し emacs 側で始末するの
も変である。本来独立に実装されているべきである。

b という事を考えると detach 時に処理できる様にするべき? 然しその場合には
新しく __detach__ という特別キーも定義する必要が出てくる。もし定義した
とすると、それを処理するのは何処で行うべきだろうか。
ble/decode/reset-default-keymap を弄れば良い様な気もするが、初回呼び出
しの際には既定で 'emacs' が代入されている為、detach が無意味に呼び出さ
れてしまう気がする。それは変だ。

a 或いは初期値を emacs 以外 (例えば safe) などにするという手もあるだろ
うか。

b 或いは初期値は空でも良いのかもしれない。例え emacs であっても初期化な
しに使える訳ではない筈だから、現状の実装で必ず初期化は実行されている
と見做すべきである様に思われる。

c 或いは safe を代入しておくのでも良いのかもしれない。然し確認してみた
所、safe であっても初期化なしには使えない様である。なので結局
_ble_decode_keymap の初期値は空文字列で良いのではないかという気がする。

もっと全然別の方法で clear される事を保証する事はできないのか。

c 例えば、emacs-editing-mode widget 自体に clear-arg を呼び出すコードを付
加しておくなど。

d それよりは change-editing-mode hook でも定義しておくのが良い様な気もす
る。然し、それだと結局 __detach__ の劣化版にしかならないので、それぐら
いならば b の __detach__ に対応するべきの気がする。

今の所 b が最有力の対処方法である。

ble/keymap:vi/needs-eol-fix については現在の keymap が vi[on]map でなければ
false になるので記にしなくて良い。

ble/keymap:vi/adjust-command-mode については

* _ble_keymap_vi_search_activate が非空の時に何か処理している。

これは様々の検索で使われている気がする。例えば単語検索等の一致で使われて
いる? この状態で vi_imap に入ったりすると値が残る気がする。と思ったが別に
値は代入されていなかった。改めてどの状況でクリアされるか確認する。

* _ble_edit_mark_active == vi_search の時にも何か処理している。

これはどうやら $_ble_keymap_vi_search_activate 経由で代入される様だ。

* _ble_keymap_vi_search_matched が何か有限の整数値を持っている時にも処理がある。

その他は特に何も無いように見える。これらの変数についてそれぞれどう設定さ
れてどう clear されるのか確認する。

うーん。上記に関しては .insert-mode の中で
ble/keymap:vi/search/clear-matched を呼び出す事にした。また、emacs mode に
対しては clear-arg の処理に際して同時に clear-matched も呼び出す事にした。

[動作確認]

o 取り敢えず __detach__ は実装して思い通りに動く事を確認した。

o また vi-bword が動作する事も確認した。テストが面倒なのでこれ以上の細かい
動作確認は省略する。

2021-07-08

* nullglob が勝手に on になってしまう現象 (reported by Lun4m) [#D1623]
Expand Down
11 changes: 9 additions & 2 deletions src/decode.sh
Expand Up @@ -258,6 +258,8 @@ function ble-decode-kbd/.initialize {
_ble_decode_KCODE_AFTER_WIDGET=$ret
ble-decode-kbd/generate-keycode __attach__
_ble_decode_KCODE_ATTACH=$ret
ble-decode-kbd/generate-keycode __detach__
_ble_decode_KCODE_DETACH=$ret

ble-decode-kbd/generate-keycode shift
_ble_decode_KCODE_SHIFT=$ret
Expand Down Expand Up @@ -1734,7 +1736,7 @@ function ble/decode/keymap#print {
##
## 呼び出し元の keymap を記録するスタック
##
_ble_decode_keymap=emacs
_ble_decode_keymap=
_ble_decode_keymap_stack=()

## @fn ble/decode/keymap/push kmap
Expand Down Expand Up @@ -3849,9 +3851,14 @@ function ble/decode/initialize {

function ble/decode/reset-default-keymap {
# 現在の ble-decode/keymap の設定
local old_base_keymap=${_ble_decode_keymap_stack[0]:-$_ble_decode_keymap}
ble-decode/INITIALIZE_DEFMAP -v _ble_decode_keymap # 0ms
_ble_decode_keymap_stack=()
ble-decode/widget/.invoke-hook "$_ble_decode_KCODE_ATTACH" # 7ms for vi-mode
if [[ $_ble_decode_keymap != "$old_base_keymap" ]]; then
[[ $old_base_keymap ]] &&
_ble_decode_keymap=$old_base_keymap ble-decode/widget/.invoke-hook "$_ble_decode_KCODE_DETACH"
ble-decode/widget/.invoke-hook "$_ble_decode_KCODE_ATTACH" # 7ms for vi-mode
fi
}

## @fn ble/decode/attach
Expand Down
1 change: 1 addition & 0 deletions src/edit.sh
Expand Up @@ -1547,6 +1547,7 @@ function ble/edit/info/.construct-content {

local type=$1 text=$2
case "$1" in
(clear) ;;
(ansi|esc)
local trace_opts=truncate
[[ $bleopt_info_display == bottom ]] && trace_opts=$trace_opts:noscrc
Expand Down
2 changes: 2 additions & 0 deletions src/util.sh
Expand Up @@ -4092,6 +4092,8 @@ function ble/util/.read-arguments-for-no-option-command {
##
function ble/util/autoload {
local file=$1; shift
ble/util/import/is-loaded "$file" && return 0

# ※$FUNCNAME は元から環境変数に設定されている場合、
# 特別変数として定義されない。
# この場合無闇にコマンドとして実行するのは危険である。
Expand Down

0 comments on commit 21d636a

Please sign in to comment.