From 9a7c8b14bb06ca0bb2b94fcedec9f01eae8e1479 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Wed, 22 Sep 2021 07:25:19 +0900 Subject: [PATCH] rlfunc: support nsearch widgets and "set-mark" in "vi_nmap" keymap --- lib/core-decode.vi_nmap-rlfunc.txt | 18 ++++----- memo/ChangeLog.md | 1 + note.txt | 65 ++++++++++++++++++++++++++++++ src/decode.sh | 10 +++++ src/edit.sh | 26 +++++++++--- 5 files changed, 105 insertions(+), 15 deletions(-) diff --git a/lib/core-decode.vi_nmap-rlfunc.txt b/lib/core-decode.vi_nmap-rlfunc.txt index ed3736b8..c6cf037d 100644 --- a/lib/core-decode.vi_nmap-rlfunc.txt +++ b/lib/core-decode.vi_nmap-rlfunc.txt @@ -55,10 +55,10 @@ glob-expand-word - glob-list-expansions - history-and-alias-expand-line vi_nmap/@edit history-and-alias-expand-line history-expand-line vi_nmap/@edit history-expand-line -history-search-backward - -history-search-forward - -history-substring-search-backward - -history-substring-search-forward - +history-search-backward history-search-backward empty=history-move +history-search-forward history-search-forward empty=history-move +history-substring-search-backward history-substring-search-backward +history-substring-search-forward history-substring-search-forward insert-comment vi-rlfunc/insert-comment insert-completions - insert-last-argument - @@ -71,10 +71,10 @@ menu-complete - menu-complete-backward - next-history history-next next-screen-line - -non-incremental-forward-search-history - -non-incremental-forward-search-history-again - -non-incremental-reverse-search-history - -non-incremental-reverse-search-history-again - +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 +non-incremental-reverse-search-history-again history-nsearch-backward-again old-menu-complete - operate-and-get-next - overwrite-mode vi_nmap/replace-mode @@ -93,7 +93,7 @@ redraw-current-line redraw-line reverse-search-history history-isearch-backward revert-line vi_nmap/revert self-insert - -set-mark - +set-mark vi_nmap/charwise-visual-mode shell-backward-kill-word - shell-backward-word - shell-expand-line - diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index 99f1e21b..85c306f9 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -66,6 +66,7 @@ - edit: support `TMOUT` for the session timeout `#D1631` 0e16dbd - edit: support bash-5.2 `READLINE_ARGUMENT` `#D1638` d347fb3 - complete: support `complete [-DI]` in old versions of Bash through `_DefaultCmD_` and `_InitialWorD_` `#D1639` 925b2cd +- rlfunc: support nsearch widgets in `vi_nmap` keymap (requested by cornfeedhobo) `#D1651` 0000000 ## Changes diff --git a/note.txt b/note.txt index bd324f7a..745f0ae6 100644 --- a/note.txt +++ b/note.txt @@ -5374,6 +5374,71 @@ bash_tips 2021-09-21 + * edit: set-mark 及び history-search-{for,back}ward を nmap で bind しようとしている [#D1651] + https://github.com/Bash-it/bash-it/pull/1884 + + これも結局は openSUSE の /etc/inputrc.keys が設定しようとしている設定である。 + 或いはもしかすると bash-it のどれかの plugin が同様に何か設定しようとしてい + る可能性もある。 + + うーん。set-mark については単純に v と同一視してしまうのが良い気がする。 + + 一方で、history-search-{for,back}ward に関しては微妙である。 + + a motion 的に実装するというのが一つの案だったが、history-search は opts に + 応じて現在の文字列を置き換える様に動作したり或いは実際に履歴を遡ったり振 + る舞いが変わる。前者の時には編集コマンドとして動作するし、後者の場合には + 移動コマンドとして動作する。どの様に実装するべきかは一定しない。 + + x 各場合に対して適切に振る舞いを変更するのも面倒だし、 + + x 更に、nsearch map の修正はしなくて良いのかという問題まで出てくる。つま + り、nmap から呼び出しているのだとすれば jk で移動できる様にするべきなの + ではないかという事になる。現状の設定では普通の文字列を入力したら普通に + 抜けて通常の文字入力をする設定になっている。 + + よく考えたら opts については bind 経由だと何も指定できないので特定の opts + である事を想定して history-search を nmap 上で動かしても良いのではないか?? + + b うーん。vi_imap に一旦抜けてから実行してしまうというのが一つの手である。 + この場合の懸念は勝手に imap に移行した事によってユーザーに混乱を来さない + のかという事である。 + + 然し nmap 専用に実装するとすると、実装の複雑さを考えると実装する価値が本 + 当にあるのか怪しいし、更に振る舞いの複雑さを考えるとそもそもユーザーがちゃ + んと使えるのかというのも怪しい。特に、bind で変な設定をした時にだけ利用で + きる物なのでユーザーが使い方に慣れてくるという事は期待し難い。そう考える + と、nmap 上で motion/edit として実装する方が余程混乱を来す様に思われる。 + + そう考えると、imap に移行して通常の history-search として振る舞わせる方が + 良い様に思われる。 + + うーん。実は history-isearch については直接束縛する様になっている。 + history-isearch は唯単に履歴項目を移動するだけなので問題ないという事なのだ + ろう。 + + うーん。振る舞いを固定してしまえば普通に edit として振る舞わせて良い気がす + る。と思ったが、vi_imap, emacs の方で動作を履歴移動に変更しているので、やは + り履歴移動として実装する。うーん。そうなると実は history-isearch と同様に修 + 正無しで nsearch を実装してしまっても良いのではという気がしてくる。 + + と思ったが、確認してみると nsearch を完了する時に eolfix が必要だし、また検 + 索開始時もカーソルを一文字ずらす必要がある様な気がする。然し抜ける時にカー + ソルが移動するとなると直感と異なる動作になる可能性もある。 + + a うーん。一つの案は history-search の opts として新しく nmap を追加して、 + 更に、history-search の選択範囲の抽出も nmap に依存する様に書き換える。 + + →opts に設定する事にするとユーザーが自分で ble-bind した時に指定し忘れる + 事になる気がするので、直接 _ble_decode_keymap を参照して動作を決定する事 + にした。 + + vi_nmap 及びその他の vi コマンドモードの中にいる時には、検索文字列を決定 + する時と一致時のカーソル位置を設定する時にカーソル位置の補正を行う事にし + た。 + + 実装した。見た感じちゃんと動いている。 + * main: work around self-modifying PROMPT_COMMAND by bash-preexec (reported by cornfeedhobo) [#D1650] https://github.com/Bash-it/bash-it/pull/1884 diff --git a/src/decode.sh b/src/decode.sh index 373238e8..2f586ba0 100644 --- a/src/decode.sh +++ b/src/decode.sh @@ -1809,6 +1809,16 @@ function ble/decode/keymap/pop { _ble_decode_keymap=${_ble_decode_keymap_stack[last]} builtin unset -v '_ble_decode_keymap_stack[last]' } +## @fn ble/decode/keymap/get-parent +## @var[out] ret +function ble/decode/keymap/get-parent { + local len=${#_ble_decode_keymap_stack[@]} + if ((len)); then + ret=${_ble_decode_keymap_stack[len-1]} + else + ret= + fi +} ## @var _ble_decode_key__seq ## 今迄に入力された未処理のキーの列を保持します diff --git a/src/edit.sh b/src/edit.sh index 2db58ae2..31e4ee58 100644 --- a/src/edit.sh +++ b/src/edit.sh @@ -1052,7 +1052,7 @@ function ble/prompt/.get-keymap-for-current-mode { ble/prompt/unit/add-hash '$_ble_decode_keymap,${_ble_decode_keymap_stack[*]}' keymap=$_ble_decode_keymap - local index=${#_ble_decode_keymap_stack} + local index=${#_ble_decode_keymap_stack[@]} while :; do case $keymap in (vi_?map|emacs) return ;; esac ((--index<0)) && break @@ -7069,7 +7069,7 @@ function ble/widget/isearch/exit-delete-forward-char { ## @fn ble/widget/history-isearch.impl opts function ble/widget/history-isearch.impl { local opts=$1 - ble-edit/content/clear-arg + ble/keymap:generic/clear-arg ble/decode/keymap/push isearch ble/util/fiberchain#initialize ble-edit/isearch @@ -7221,12 +7221,21 @@ function ble-edit/nsearch/.goto-match { _ble_edit_nsearch_match=$index _ble_edit_nsearch_index=$index _ble_edit_mark=$beg + local is_end_marker= case :$opts: in (*:point=begin:*) _ble_edit_ind=0 ;; - (*:point=end:*) _ble_edit_ind=${#_ble_edit_str} ;; + (*:point=end:*) _ble_edit_ind=${#_ble_edit_str} is_end_marker=1 ;; (*:point=match-begin:*) _ble_edit_ind=$beg ;; - (*:point=match-end:*|*) _ble_edit_ind=$end ;; + (*:point=match-end:*|*) _ble_edit_ind=$end is_end_marker=1 ;; esac + + # vi_nmap の中にいる時は一致範囲の最後の文字にカーソルを置く + if [[ $is_end_marker ]] && ((_ble_edit_ind)); then + if local ret; ble/decode/keymap/get-parent; [[ $ret == vi_[noxs]map ]]; then + ble-edit/content/bolp || ((_ble_edit_ind--)) + fi + fi + if ((beg!=end)); then _ble_edit_mark_active=nsearch else @@ -7388,7 +7397,12 @@ function ble/widget/history-search { elif [[ :$opts: == *:again:* ]]; then _ble_edit_nsearch_needle=$_ble_edit_nsearch_input else - _ble_edit_nsearch_needle=${_ble_edit_str::_ble_edit_ind} + local len=$_ble_edit_ind + if [[ $_ble_decode_keymap == vi_[noxs]map ]]; then + # vi_nmap の中にいる時は現在カーソルがある文字も検索文字列に含める + ble-edit/content/eolp || ((len++)) + fi + _ble_edit_nsearch_needle=${_ble_edit_str::len} fi # 検索文字列が空の時は別の動作を行う @@ -7412,7 +7426,7 @@ function ble/widget/history-search { fi _ble_edit_nsearch_prev=$_ble_edit_nsearch_needle - ble-edit/content/clear-arg + ble/keymap:generic/clear-arg _ble_edit_nsearch_stack=() local index; ble/history/get-index