diff options
Diffstat (limited to '.local/src/blesh/keymap')
-rw-r--r-- | .local/src/blesh/keymap/emacs.sh | 163 | ||||
-rw-r--r-- | .local/src/blesh/keymap/vi.sh | 6171 | ||||
-rw-r--r-- | .local/src/blesh/keymap/vi_digraph.sh | 51 | ||||
-rw-r--r-- | .local/src/blesh/keymap/vi_digraph.txt | 1304 | ||||
-rw-r--r-- | .local/src/blesh/keymap/vi_test.sh | 363 |
5 files changed, 8052 insertions, 0 deletions
diff --git a/.local/src/blesh/keymap/emacs.sh b/.local/src/blesh/keymap/emacs.sh new file mode 100644 index 0000000..430e213 --- /dev/null +++ b/.local/src/blesh/keymap/emacs.sh @@ -0,0 +1,163 @@ +# this script is a part of blesh (https://github.com/akinomyoga/ble.sh) under BSD-3-Clause license +ble/is-function ble-edit/bind/load-editing-mode:emacs && return 0 +function ble-edit/bind/load-editing-mode:emacs { :; } +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=( + self-insert + batch-insert + nop + magic-space + copy{,-forward,-backward}-{c,f,s,u}word + copy-region{,-or} + clear-screen + command-help + display-shell-version + redraw-line +) +function ble/keymap:emacs/is-command-white { + if [[ $1 == ble/widget/self-insert ]]; then + return 0 + elif [[ $1 == ble/widget/* ]]; then + local IFS=$_ble_term_IFS + local cmd=${1#ble/widget/}; cmd=${cmd%%["$_ble_term_IFS"]*} + [[ $cmd == emacs/* || " ${_ble_keymap_emacs_white_list[*]} " == *" $cmd "* ]] && return 0 + fi + return 1 +} +function ble/widget/emacs/__before_widget__ { + if ! ble/keymap:emacs/is-command-white "$WIDGET"; then + ble-edit/undo/add + fi +} +function ble/widget/emacs/undo { + local arg; ble-edit/content/get-arg 1 + ble-edit/undo/undo "$arg" || ble/widget/.bell 'no more older undo history' +} +function ble/widget/emacs/redo { + local arg; ble-edit/content/get-arg 1 + ble-edit/undo/redo "$arg" || ble/widget/.bell 'no more recent undo history' +} +function ble/widget/emacs/revert { + local arg; ble-edit/content/clear-arg + ble-edit/undo/revert +} +_ble_keymap_emacs_modeline=:: +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_emacs_modeline +function ble/keymap:emacs/update-mode-name { + local opt_multiline=; [[ $_ble_edit_str == *$'\n'* ]] && opt_multiline=1 + local footprint=$opt_multiline:$_ble_edit_arg:$_ble_edit_kbdmacro_record + [[ $footprint == "$_ble_keymap_emacs_modeline" ]] && return 0 + _ble_keymap_emacs_modeline=$footprint + local name= + [[ $opt_multiline ]] && name=$'\e[1m-- MULTILINE --\e[m' + local info= + [[ $_ble_edit_arg ]] && + info=$info$' (arg: \e[1;34m'$_ble_edit_arg$'\e[m)' + [[ $_ble_edit_kbdmacro_record ]] && + info=$info$' \e[1;31mREC\e[m' + [[ ! $info && $opt_multiline ]] && + info=$' (\e[35mRET\e[m or \e[35mC-m\e[m: insert a newline, \e[35mC-j\e[m: run)' + [[ $name ]] || info=${info#' '} + name=$name$info + ble/edit/info/default ansi "$name" +} +function ble/widget/emacs/__after_widget__ { + ble/keymap:emacs/update-mode-name +} +function ble/widget/emacs/quoted-insert-char { + _ble_edit_mark_active= + _ble_decode_char__hook=ble/widget/emacs/quoted-insert-char.hook + return 147 +} +function ble/widget/emacs/quoted-insert-char.hook { + ble/widget/quoted-insert-char.hook + ble/keymap:emacs/update-mode-name +} +function ble/widget/emacs/quoted-insert { + _ble_edit_mark_active= + _ble_decode_key__hook=ble/widget/emacs/quoted-insert.hook + return 147 +} +function ble/widget/emacs/quoted-insert.hook { + ble/widget/quoted-insert.hook + ble/keymap:emacs/update-mode-name +} +function ble/widget/emacs/bracketed-paste { + ble/widget/bracketed-paste + _ble_edit_bracketed_paste_proc=ble/widget/emacs/bracketed-paste.proc + return 147 +} +function ble/widget/emacs/bracketed-paste.proc { + ble/widget/bracketed-paste.proc "$@" + ble/keymap:emacs/update-mode-name +} +function ble-decode/keymap:emacs/define { + local ble_bind_nometa= + ble-decode/keymap:safe/bind-common + ble-decode/keymap:safe/bind-history + ble-decode/keymap:safe/bind-complete + ble-decode/keymap:safe/bind-arg + ble-bind -f 'C-d' 'delete-region-or delete-forward-char-or-exit' + ble-bind -f 'M-^' history-expand-line + ble-bind -f 'SP' magic-space + ble-bind -f __attach__ safe/__attach__ + ble-bind -f __before_widget__ emacs/__before_widget__ + ble-bind -f __after_widget__ emacs/__after_widget__ + ble-bind -f __line_limit__ __line_limit__ + ble-bind -f 'C-c' discard-line + ble-bind -f 'C-j' accept-line + ble-bind -f 'C-RET' accept-line + ble-bind -f 'C-m' accept-single-line-or-newline + ble-bind -f 'RET' accept-single-line-or-newline + ble-bind -f 'C-o' accept-and-next + ble-bind -f 'C-x C-e' edit-and-execute-command + ble-bind -f 'M-#' insert-comment + ble-bind -f 'M-C-e' shell-expand-line + ble-bind -f 'M-&' tilde-expand + ble-bind -f 'C-g' bell + ble-bind -f 'C-x C-g' bell + ble-bind -f 'C-M-g' bell + ble-bind -f 'C-l' clear-screen + ble-bind -f 'C-M-l' redraw-line + ble-bind -f 'f1' command-help + ble-bind -f 'C-x C-v' display-shell-version + ble-bind -c 'C-z' fg + ble-bind -c 'M-z' fg + ble-bind -f 'C-\' bell + ble-bind -f 'C-^' bell + ble-bind -f 'C-_' emacs/undo + ble-bind -f 'C-DEL' emacs/undo + ble-bind -f 'C-BS' emacs/undo + ble-bind -f 'C-/' emacs/undo + ble-bind -f 'C-x u' emacs/undo + ble-bind -f 'C-x C-u' emacs/undo + ble-bind -f 'C-x U' emacs/redo + ble-bind -f 'C-x C-S-u' emacs/redo + ble-bind -f 'M-r' emacs/revert + ble-bind -f 'C-q' emacs/quoted-insert + ble-bind -f 'C-v' emacs/quoted-insert + ble-bind -f paste_begin emacs/bracketed-paste +} +function ble-decode/keymap:emacs/initialize { + local fname_keymap_cache=$_ble_base_cache/keymap.emacs + if [[ -s $fname_keymap_cache && + $fname_keymap_cache -nt $_ble_base/keymap/emacs.sh && + $fname_keymap_cache -nt $_ble_base/lib/init-cmap.sh ]]; then + source "$fname_keymap_cache" && return 0 + fi + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs..." + { + ble/decode/keymap#load isearch dump + ble/decode/keymap#load nsearch dump + ble/decode/keymap#load emacs dump + } 3>| "$fname_keymap_cache" + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs... done" +} +ble-decode/keymap:emacs/initialize +blehook/invoke keymap_load +blehook/invoke keymap_emacs_load +return 0 diff --git a/.local/src/blesh/keymap/vi.sh b/.local/src/blesh/keymap/vi.sh new file mode 100644 index 0000000..ccf8b84 --- /dev/null +++ b/.local/src/blesh/keymap/vi.sh @@ -0,0 +1,6171 @@ +# this script is a part of blesh (https://github.com/akinomyoga/ble.sh) under BSD-3-Clause license +ble/is-function ble-edit/bind/load-editing-mode:vi && return 0 +function ble-edit/bind/load-editing-mode:vi { :; } +source "$_ble_base/keymap/vi_digraph.sh" +bleopt/declare -n keymap_vi_macro_depth 64 +function ble/keymap:vi/k2c { + local key=$1 + local flag=$((key&_ble_decode_MaskFlag)) char=$((key&_ble_decode_MaskChar)) + if ((flag==0&&(32<=char&&char<_ble_decode_FunctionKeyBase))); then + ret=$char + return 0 + elif ((flag==_ble_decode_Ctrl&&63<=char&&char<128&&(char&0x1F)!=0)); then + ((char=char==63?127:char&0x1F)) + ret=$char + return 0 + else + return 1 + fi +} +function ble/string#index-of-chars { + local chars=$2 index=${3:-0} + local text=${1:index} + local cut=${text%%["$chars"]*} + if ((${#cut}<${#text})); then + ((ret=index+${#cut})) + return 0 + else + ret=-1 + return 1 + fi +} +function ble/string#last-index-of-chars { + local text=$1 chars=$2 index=$3 + [[ $index ]] && text=${text::index} + local cut=${text%["$chars"]*} + if ((${#cut}<${#text})); then + ((ret=${#cut})) + return 0 + else + ret=-1 + return 1 + fi +} +function ble-edit/content/nonbol-eolp { + local pos=${1:-$_ble_edit_ind} + ! ble-edit/content/bolp "$pos" && ble-edit/content/eolp "$pos" +} +function ble/keymap:vi/string#encode-rot13 { + local text=$1 + local -a buff=() ch + for ((i=0;i<${#text};i++)); do + ch=${text:i:1} + if [[ $ch == [A-Z] ]]; then + ch=${_ble_util_string_upper_list%%"$ch"*} + ch=${_ble_util_string_upper_list:(${#ch}+13)%26:1} + elif [[ $ch == [a-z] ]]; then + ch=${_ble_util_string_lower_list%%"$ch"*} + ch=${_ble_util_string_lower_list:(${#ch}+13)%26:1} + fi + ble/array#push buff "$ch" + done + IFS= builtin eval 'ret="${buff[*]-}"' +} +_ble_keymap_vi_REX_WORD=$'[a-zA-Z0-9_]+|[!-/:-@[-`{-~]+|[^ \t\na-zA-Z0-9!-/:-@[-`{-~]+' +function ble/widget/vi_imap/__default__ { + local flag=$((KEYS[0]&_ble_decode_MaskFlag)) code=$((KEYS[0]&_ble_decode_MaskChar)) + if ((flag&_ble_decode_Meta)); then + ble/keymap:vi/imap-repeat/pop + local esc=27 # ESC + ble/decode/widget/skip-lastwidget + ble/decode/widget/redispatch-by-keys "$esc" $((KEYS[0]&~_ble_decode_Meta)) "${KEYS[@]:1}" + return 0 + fi + if local ret; ble/keymap:vi/k2c "${KEYS[0]}"; then + local -a KEYS; KEYS=("$ret") + ble/widget/self-insert + return 0 + fi + return 125 +} +function ble/widget/vi-command/decompose-meta { + local flag=$((KEYS[0]&_ble_decode_MaskFlag)) code=$((KEYS[0]&_ble_decode_MaskChar)) + if ((flag&_ble_decode_Meta)); then + local esc=$((_ble_decode_Ctrl|0x5b)) # C-[ (もしくは esc=27 ESC?) + ble/decode/widget/skip-lastwidget + ble/decode/widget/redispatch-by-keys "$esc" $((KEYS[0]&~_ble_decode_Meta)) "${KEYS[@]:1}" + return 0 + fi + return 125 +} +function ble/widget/vi_omap/__default__ { + ble/widget/vi-command/decompose-meta || ble/widget/vi-command/bell + return 0 +} +function ble/widget/vi_omap/cancel { + ble/keymap:vi/adjust-command-mode + return 0 +} +_ble_keymap_vi_irepeat_count= +_ble_keymap_vi_irepeat=() +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_irepeat_count \ + _ble_keymap_vi_irepeat +function ble/keymap:vi/imap-repeat/pop { + local top_index=$((${#_ble_keymap_vi_irepeat[*]}-1)) + ((top_index>=0)) && builtin unset -v '_ble_keymap_vi_irepeat[top_index]' +} +function ble/keymap:vi/imap-repeat/push { + local IFS=$_ble_term_IFS + ble/array#push _ble_keymap_vi_irepeat "${KEYS[*]-}:$WIDGET" +} +function ble/keymap:vi/imap-repeat/reset { + local count=${1-} + _ble_keymap_vi_irepeat_count= + _ble_keymap_vi_irepeat=() + ((count>1)) && _ble_keymap_vi_irepeat_count=$count +} +function ble/keymap:vi/imap-repeat/process { + if ((_ble_keymap_vi_irepeat_count>1)); then + local repeat=$_ble_keymap_vi_irepeat_count + local -a widgets; widgets=("${_ble_keymap_vi_irepeat[@]}") + local i widget + for ((i=1;i<repeat;i++)); do + for widget in "${widgets[@]}"; do + ble/decode/widget/call "${widget#*:}" ${widget%%:*} + done + done + fi +} +function ble/keymap:vi/imap/invoke-widget { + local WIDGET=$1 + local -a KEYS; KEYS=("${@:2}") + ble/keymap:vi/imap-repeat/push + builtin eval -- "$WIDGET" +} +_ble_keymap_vi_imap_white_list=( + self-insert + batch-insert + nop + magic-space + delete-backward-{c,f,s,u}word + copy{,-forward,-backward}-{c,f,s,u}word + copy-region{,-or} + clear-screen + command-help + display-shell-version + redraw-line +) +function ble/keymap:vi/imap/is-command-white { + if [[ $1 == ble/widget/self-insert ]]; then + return 0 + elif [[ $1 == ble/widget/* ]]; then + local IFS=$_ble_term_IFS + local cmd=${1#ble/widget/}; cmd=${cmd%%["$_ble_term_IFS"]*} + [[ $cmd == vi_imap/* || " ${_ble_keymap_vi_imap_white_list[*]} " == *" $cmd "* ]] && return 0 + fi + return 1 +} +function ble/widget/vi_imap/__before_widget__ { + if ble/keymap:vi/imap/is-command-white "$WIDGET"; then + ble/keymap:vi/imap-repeat/push + else + if ((_ble_keymap_vi_mark_edit_dbeg>=0)); then + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/repeat/record-insert + ble/keymap:vi/mark/start-edit-area + fi + ble/keymap:vi/imap-repeat/reset + fi +} +function ble/widget/vi_imap/complete { + ble/keymap:vi/imap-repeat/pop + ble/keymap:vi/undo/add more + ble/widget/complete "$@" +} +function ble/keymap:vi/complete/insert.hook { + [[ $_ble_decode_keymap == vi_imap || + $_ble_decode_keymap == auto_complete ]] || return 1 + local original=${comp_text:insert_beg:insert_end-insert_beg} + local q="'" Q="'\''" + local WIDGET="ble/widget/complete-insert '${original//$q/$Q}' '${insert//$q/$Q}' '${suffix//$q/$Q}'" + ble/keymap:vi/imap-repeat/push + [[ $_ble_decode_keymap == vi_imap ]] && + ble/keymap:vi/undo/add more +} +blehook complete_insert+=ble/keymap:vi/complete/insert.hook +function ble-decode/keymap:vi_imap/bind-complete { + ble-bind -f 'C-i' 'vi_imap/complete' + ble-bind -f 'TAB' 'vi_imap/complete' + ble-bind -f 'C-TAB' 'menu-complete' + ble-bind -f 'S-C-i' 'menu-complete backward' + ble-bind -f 'S-TAB' 'menu-complete backward' + ble-bind -f 'auto_complete_enter' 'auto-complete-enter' + ble-bind -f 'C-x /' 'menu-complete context=filename' + ble-bind -f 'C-x ~' 'menu-complete context=username' + ble-bind -f 'C-x $' 'menu-complete context=variable' + ble-bind -f 'C-x @' 'menu-complete context=hostname' + ble-bind -f 'C-x !' 'menu-complete context=command' + ble-bind -f 'C-]' 'sabbrev-expand' + ble-bind -f 'C-x C-r' 'dabbrev-expand' + ble-bind -f 'C-x *' 'complete insert_all:context=glob' + ble-bind -f 'C-x g' 'complete show_menu:context=glob' +} +_ble_keymap_vi_insert_overwrite= +_ble_keymap_vi_insert_leave= +_ble_keymap_vi_single_command= +_ble_keymap_vi_single_command_overwrite= +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_insert_overwrite \ + _ble_keymap_vi_insert_leave \ + _ble_keymap_vi_single_command \ + _ble_keymap_vi_single_command_overwrite +bleopt/declare -n keymap_vi_mode_string_nmap $'\e[1m~\e[m' +bleopt/declare -o keymap_vi_nmap_name keymap_vi_mode_string_nmap +bleopt/declare -v term_vi_imap '' +bleopt/declare -v term_vi_nmap '' +bleopt/declare -v term_vi_omap '' +bleopt/declare -v term_vi_xmap '' +bleopt/declare -v term_vi_smap '' +bleopt/declare -v term_vi_cmap '' +bleopt/declare -v keymap_vi_imap_cursor '' +bleopt/declare -v keymap_vi_nmap_cursor '' +bleopt/declare -v keymap_vi_omap_cursor '' +bleopt/declare -v keymap_vi_xmap_cursor '' +bleopt/declare -v keymap_vi_smap_cursor '' +bleopt/declare -v keymap_vi_cmap_cursor '' +function ble/keymap:vi/.process-cursor-options { + local keymap=${FUNCNAME[1]#bleopt/check:keymap_}; keymap=${keymap%_cursor} + ble-bind -m "$keymap" --cursor "$value" + local locate=$'\e[32m'$bleopt_source:$bleopt_lineno$'\e[m' + ble/util/print-lines \ + "bleopt ($locate): The option 'keymap_${keymap}_cursor' has been removed." \ + " Please use 'ble-bind -m $keymap --cursor $value' instead." >&2 +} +function bleopt/check:keymap_vi_imap_cursor { ble/keymap:vi/.process-cursor-options; } +function bleopt/check:keymap_vi_nmap_cursor { ble/keymap:vi/.process-cursor-options; } +function bleopt/check:keymap_vi_omap_cursor { ble/keymap:vi/.process-cursor-options; } +function bleopt/check:keymap_vi_xmap_cursor { ble/keymap:vi/.process-cursor-options; } +function bleopt/check:keymap_vi_smap_cursor { ble/keymap:vi/.process-cursor-options; } +function bleopt/check:keymap_vi_cmap_cursor { ble/keymap:vi/.process-cursor-options; } +function bleopt/obsolete:keymap_vi_imap_cursor { :; } +function bleopt/obsolete:keymap_vi_nmap_cursor { :; } +function bleopt/obsolete:keymap_vi_omap_cursor { :; } +function bleopt/obsolete:keymap_vi_xmap_cursor { :; } +function bleopt/obsolete:keymap_vi_smap_cursor { :; } +function bleopt/obsolete:keymap_vi_cmap_cursor { :; } +bleopt/declare -v keymap_vi_mode_show 1 +function bleopt/check:keymap_vi_mode_show { + local bleopt_keymap_vi_mode_show=$value + [[ $_ble_attached ]] && + ble/keymap:vi/update-mode-name + return 0 +} +bleopt/declare -v keymap_vi_mode_update_prompt '' +bleopt/declare -v keymap_vi_mode_name_insert 'INSERT' +bleopt/declare -v keymap_vi_mode_name_replace 'REPLACE' +bleopt/declare -v keymap_vi_mode_name_vreplace 'VREPLACE' +bleopt/declare -v keymap_vi_mode_name_visual 'VISUAL' +bleopt/declare -v keymap_vi_mode_name_select 'SELECT' +bleopt/declare -v keymap_vi_mode_name_linewise 'LINE' +bleopt/declare -v keymap_vi_mode_name_blockwise 'BLOCK' +function bleopt/check:keymap_vi_mode_name_insert { ble/keymap:vi/update-mode-name; } +function bleopt/check:keymap_vi_mode_name_replace { ble/keymap:vi/update-mode-name; } +function bleopt/check:keymap_vi_mode_name_vreplace { ble/keymap:vi/update-mode-name; } +function bleopt/check:keymap_vi_mode_name_visual { ble/keymap:vi/update-mode-name; } +function bleopt/check:keymap_vi_mode_name_select { ble/keymap:vi/update-mode-name; } +function bleopt/check:keymap_vi_mode_name_linewise { ble/keymap:vi/update-mode-name; } +function bleopt/check:keymap_vi_mode_name_blockwise { ble/keymap:vi/update-mode-name; } +function ble/keymap:vi/script/get-vi-keymap { + ble/prompt/unit/add-hash '$_ble_decode_keymap,${_ble_decode_keymap_stack[*]}' + local i=${#_ble_decode_keymap_stack[@]} + keymap=$_ble_decode_keymap + while [[ $keymap != vi_?map || $keymap == emacs ]]; do + ((i--)) || return 1 + keymap=${_ble_decode_keymap_stack[i]} + done + [[ $keymap == vi_?map ]] +} +function ble/keymap:vi/script/get-mode { + ble/prompt/unit/add-hash '$_ble_decode_keymap,${_ble_decode_keymap_stack[*]}' + ble/prompt/unit/add-hash '$_ble_keymap_vi_single_command,$_ble_edit_mark_active' + mode= + local keymap; ble/keymap:vi/script/get-vi-keymap + if [[ $_ble_keymap_vi_single_command || $keymap == vi_imap ]]; then + local overwrite= + if [[ $keymap == vi_imap ]]; then + overwrite=$_ble_edit_overwrite_mode + elif [[ $keymap == vi_[noxs]map ]]; then + overwrite=$_ble_keymap_vi_single_command_overwrite + fi + case $overwrite in + ('') mode=i ;; + (R) mode=R ;; + (*) mode=$'\x12' ;; # C-r + esac + fi + case $keymap:${_ble_edit_mark_active%+} in + (vi_xmap:vi_line) mode=$mode'V' ;; + (vi_xmap:vi_block)mode=$mode$'\x16' ;; # C-v + (vi_xmap:*) mode=$mode'v' ;; + (vi_smap:vi_line) mode=$mode'S' ;; + (vi_smap:vi_block)mode=$mode$'\x13' ;; # C-s + (vi_smap:*) mode=$mode's' ;; + (vi_[no]map:*) mode=$mode'n' ;; + (vi_cmap:*) mode=$mode'c' ;; + (vi_imap:*) ;; + (*:*) mode=$mode'?' ;; + esac +} +_ble_keymap_vi_mode_name_dirty= +function ble/keymap:vi/info_reveal.hook { + [[ $_ble_keymap_vi_mode_name_dirty ]] || return 0 + _ble_keymap_vi_mode_name_dirty= + ble/keymap:vi/update-mode-name +} +blehook info_reveal+=ble/keymap:vi/info_reveal.hook +function ble/keymap:vi/update-mode-name { + if [[ ! $_ble_attached ]] || ble/edit/is-command-layout; then + _ble_keymap_vi_mode_name_dirty=1 + return 0 + fi + local keymap + ble/keymap:vi/script/get-vi-keymap || return 0 + if [[ $keymap == vi_imap ]]; then + ble/util/buffer "$bleopt_term_vi_imap" + elif [[ $keymap == vi_nmap ]]; then + ble/util/buffer "$bleopt_term_vi_nmap" + elif [[ $keymap == vi_xmap ]]; then + ble/util/buffer "$bleopt_term_vi_xmap" + elif [[ $keymap == vi_smap ]]; then + ble/util/buffer "$bleopt_term_vi_smap" + elif [[ $keymap == vi_omap ]]; then + ble/util/buffer "$bleopt_term_vi_omap" + elif [[ $keymap == vi_cmap ]]; then + ble/edit/info/default text '' + ble/util/buffer "$bleopt_term_vi_cmap" + return 0 + fi + [[ $bleopt_keymap_vi_mode_update_prompt ]] && ble/prompt/clear + local name= + if [[ $bleopt_keymap_vi_mode_show ]]; then + local show= overwrite= + if [[ $keymap == vi_imap ]]; then + show=1 overwrite=$_ble_edit_overwrite_mode + elif [[ $_ble_keymap_vi_single_command && ( $keymap == vi_nmap || $keymap == vi_omap ) ]]; then + show=1 overwrite=$_ble_keymap_vi_single_command_overwrite + elif [[ $keymap == vi_[xs]map ]]; then + show=x overwrite=$_ble_keymap_vi_single_command_overwrite + else + name=$bleopt_keymap_vi_mode_string_nmap + fi + fi + if [[ $show ]]; then + if [[ $overwrite == R ]]; then + name=$bleopt_keymap_vi_mode_name_replace + elif [[ $overwrite ]]; then + name=$bleopt_keymap_vi_mode_name_vreplace + else + name=$bleopt_keymap_vi_mode_name_insert + fi + if [[ $_ble_keymap_vi_single_command ]]; then + local ret; ble/string#tolower "$name"; name="($ret)" + fi + if [[ $show == x ]]; then + local mark_type=${_ble_edit_mark_active%+} + local visual_name=$bleopt_keymap_vi_mode_name_visual + [[ $keymap == vi_smap ]] && visual_name=$bleopt_keymap_vi_mode_name_select + if [[ $mark_type == vi_line ]]; then + visual_name=$visual_name' '$bleopt_keymap_vi_mode_name_linewise + elif [[ $mark_type == vi_block ]]; then + visual_name=$visual_name' '$bleopt_keymap_vi_mode_name_blockwise + fi + if [[ $_ble_keymap_vi_single_command ]]; then + name="$name $visual_name" + else + name=$visual_name + fi + fi + name=$'\e[1m-- '$name$' --\e[m' + fi + if [[ $_ble_keymap_vi_reg_record ]]; then + name=$name${name:+' '}$'\e[1;31mREC @'$_ble_keymap_vi_reg_record_char$'\e[m' + elif [[ $_ble_edit_kbdmacro_record ]]; then + name=$name${name:+' '}$'\e[1;31mREC\e[m' + fi + ble/edit/info/default ansi "$name" # 6ms +} +function ble/widget/vi_imap/normal-mode.impl { + local opts=$1 + ble/keymap:vi/mark/set-local-mark 94 "$_ble_edit_ind" # `^ + ble/keymap:vi/mark/end-edit-area + [[ :$opts: == *:InsertLeave:* ]] && builtin eval -- "$_ble_keymap_vi_insert_leave" + _ble_edit_mark_active= + _ble_edit_overwrite_mode= + _ble_keymap_vi_insert_leave= + _ble_keymap_vi_single_command= + _ble_keymap_vi_single_command_overwrite= + ble-edit/content/bolp || ((_ble_edit_ind--)) + ble/decode/keymap/push vi_nmap +} +function ble/widget/vi_imap/normal-mode { + ble-edit/content/clear-arg + ble/keymap:vi/imap-repeat/pop + ble/keymap:vi/imap-repeat/process + ble/keymap:vi/repeat/record-insert + ble/widget/vi_imap/normal-mode.impl InsertLeave + ble/keymap:vi/update-mode-name + return 0 +} +function ble/widget/vi_imap/normal-mode-without-insert-leave { + ble-edit/content/clear-arg + ble/keymap:vi/imap-repeat/pop + ble/keymap:vi/repeat/record-insert + ble/widget/vi_imap/normal-mode.impl + ble/keymap:vi/update-mode-name + return 0 +} +function ble/widget/vi_imap/single-command-mode { + ble-edit/content/clear-arg + local single_command=1 + local single_command_overwrite=$_ble_edit_overwrite_mode + ble-edit/content/eolp && _ble_keymap_vi_single_command=2 + ble/keymap:vi/imap-repeat/pop + ble/widget/vi_imap/normal-mode.impl + _ble_keymap_vi_single_command=$single_command + _ble_keymap_vi_single_command_overwrite=$single_command_overwrite + ble/keymap:vi/update-mode-name + return 0 +} +function ble/keymap:vi/needs-eol-fix { + [[ $_ble_decode_keymap == vi_nmap || $_ble_decode_keymap == vi_omap ]] || return 1 + [[ $_ble_keymap_vi_single_command ]] && return 1 + local index=${1:-$_ble_edit_ind} + ble-edit/content/nonbol-eolp "$index" +} +function ble/keymap:vi/adjust-command-mode { + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + ble/keymap:vi/xmap/remove-eol-extension + fi + local kmap_popped= + if [[ $_ble_decode_keymap == vi_omap ]]; then + ble/decode/keymap/pop + kmap_popped=1 + fi + if [[ $_ble_keymap_vi_search_activate ]]; then + if [[ $_ble_decode_keymap != vi_[xs]map ]]; then + _ble_edit_mark_active=$_ble_keymap_vi_search_activate + fi + _ble_keymap_vi_search_matched=1 + _ble_keymap_vi_search_activate= + else + [[ $_ble_edit_mark_active == vi_search ]] && _ble_edit_mark_active= + ((_ble_keymap_vi_search_matched)) && _ble_keymap_vi_search_matched= + fi + if [[ $_ble_decode_keymap == vi_nmap && $_ble_keymap_vi_single_command ]]; then + if ((_ble_keymap_vi_single_command==2)); then + local index=$((_ble_edit_ind+1)) + ble-edit/content/nonbol-eolp "$index" && _ble_edit_ind=$index + fi + ble/widget/vi_nmap/.insert-mode 1 "$_ble_keymap_vi_single_command_overwrite" resume + ble/keymap:vi/repeat/clear-insert + elif [[ $kmap_popped ]]; then + ble/keymap:vi/update-mode-name + fi + return 0 +} +function ble/widget/vi-command/bell { + ble/widget/.bell "$1" + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi_nmap/.insert-mode { + [[ $_ble_decode_keymap == vi_[xs]map ]] && ble/decode/keymap/pop + [[ $_ble_decode_keymap == vi_omap ]] && ble/decode/keymap/pop + local arg=$1 overwrite=$2 + ble/keymap:vi/imap-repeat/reset "$arg" + _ble_edit_mark_active= + _ble_edit_overwrite_mode=$overwrite + _ble_keymap_vi_insert_leave= + _ble_keymap_vi_insert_overwrite=$overwrite + _ble_keymap_vi_single_command= + _ble_keymap_vi_single_command_overwrite= + ble/keymap:vi/search/clear-matched + ble/decode/keymap/pop + ble/keymap:vi/update-mode-name + ble/keymap:vi/mark/start-edit-area + if [[ :$opts: != *:resume:* ]]; then + ble/keymap:vi/mark/commit-edit-area "$_ble_edit_ind" "$_ble_edit_ind" + fi +} +function ble/widget/vi_nmap/insert-mode { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/append-mode { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + if ! ble-edit/content/eolp; then + ((_ble_edit_ind++)) + fi + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/append-mode-at-end-of-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret; ble-edit/content/find-logical-eol + _ble_edit_ind=$ret + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/insert-mode-at-beginning-of-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret; ble-edit/content/find-logical-bol + _ble_edit_ind=$ret + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/insert-mode-at-first-non-space { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/first-non-space + [[ ${_ble_edit_str:_ble_edit_ind:1} == [$' \t'] ]] && + ((_ble_edit_ind++)) # 逆eol補正 + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/insert-mode-at-previous-point { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + ble/keymap:vi/mark/get-local-mark 94 && _ble_edit_ind=$ret + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/replace-mode { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi_nmap/.insert-mode "$ARG" R + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/virtual-replace-mode { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi_nmap/.insert-mode "$ARG" 1 + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/accept-line { + ble/keymap:vi/clear-arg + ble/widget/vi_nmap/.insert-mode + ble/keymap:vi/repeat/clear-insert + [[ $_ble_keymap_vi_reg_record ]] && + ble/widget/vi_nmap/record-register + ble/widget/default/accept-line +} +function ble/widget/vi-command/edit-and-execute-command { + ble/keymap:vi/clear-arg + ble/widget/vi_nmap/.insert-mode + ble/keymap:vi/repeat/clear-insert + [[ $_ble_keymap_vi_reg_record ]] && + ble/widget/vi_nmap/record-register + ble/widget/edit-and-execute-command +} +_ble_keymap_vi_oparg= +_ble_keymap_vi_opfunc= +_ble_keymap_vi_reg= +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_oparg \ + _ble_keymap_vi_opfunc \ + _ble_keymap_vi_reg +_ble_keymap_vi_register=() +_ble_keymap_vi_register_onplay= +function ble/keymap:vi/clear-arg { + _ble_edit_arg= + _ble_keymap_vi_oparg= + _ble_keymap_vi_opfunc= + _ble_keymap_vi_reg= +} +function ble/keymap:vi/get-arg { + local default_value=$1 + REG=$_ble_keymap_vi_reg + FLAG=$_ble_keymap_vi_opfunc + if [[ ! $_ble_edit_arg && ! $_ble_keymap_vi_oparg ]]; then + ARG=$default_value + else + ARG=$((10#0${_ble_edit_arg:-1}*10#0${_ble_keymap_vi_oparg:-1})) + fi + ble/keymap:vi/clear-arg +} +function ble/keymap:vi/register#load { + local reg=$1 + if [[ $reg ]] && ((reg!=34)); then + if [[ $reg == 37 ]]; then # "% + ble-edit/content/push-kill-ring "$HISTFILE" '' + return 0 + fi + local value=${_ble_keymap_vi_register[reg]} + if [[ $value == */* ]]; then + ble-edit/content/push-kill-ring "${value#*/}" "${value%%/*}" + return 0 + else + ble-edit/content/push-kill-ring + return 1 + fi + fi +} +function ble/keymap:vi/register#set { + local reg=$1 type=$2 content=$3 + if [[ $reg == +* ]]; then + local value=${_ble_keymap_vi_register[reg]} + if [[ $value == */* ]]; then + local otype=${value%%/*} + local oring=${value#*/} + if [[ $otype == L ]]; then + if [[ $type == q ]]; then + type=L content=${oring%$'\n'}$content # V + * → V + else + type=L content=$oring$content # V + * → V + fi + elif [[ $type == L ]]; then + type=L content=$oring$'\n'$content # C-v + V, v + V → V + elif [[ $otype == B:* ]]; then + if [[ $type == B:* ]]; then + type=$otype' '${type#B:} + content=$oring$'\n'$content # C-v + C-v → C-v + elif [[ $type == q ]]; then + local ret; ble/string#count-char "$content" $'\n' + ble/string#repeat ' 0' "$ret" + type=$otype$ret + content=$oring$$content # C-v + q → C-v + else + local ret; ble/string#count-char "$content" $'\n' + ble/string#repeat ' 0' $((ret+1)) + type=$otype$ret + content=$oring$'\n'$content # C-v + v → C-v + fi + else + type= content=$oring$content # v + C-v, v + v, v + q → v + fi + fi + fi + [[ $type == L && $content != *$'\n' ]] && content=$content$'\n' + local suppress_default= + [[ $type == q ]] && type= suppress_default=1 + if [[ ! $reg ]] || ((reg==34)); then # "" + ble-edit/content/push-kill-ring "$content" "$type" + return 0 + elif ((reg==58||reg==46||reg==37||reg==126)); then # ": ". "% "~ + ble/widget/.bell "attempted to write on a read-only register #$reg" + return 1 + elif ((reg==95)); then # "_ + return 0 + else + if [[ ! $suppress_default ]]; then + ble-edit/content/push-kill-ring "$content" "$type" + fi + _ble_keymap_vi_register[reg]=$type/$content + return 0 + fi +} +function ble/keymap:vi/register#set-yank { + ble/keymap:vi/register#set "$@" || return 1 + local reg=$1 type=$2 content=$3 + if [[ $reg == '' || $reg == 34 ]]; then + ble/keymap:vi/register#set 48 "$type" "$content" # "0 + fi +} +_ble_keymap_vi_register_49_widget_list=( + ble/widget/vi-command/search-matchpair-or + ble/widget/vi-command/percentage-line + ble/widget/vi-command/goto-mark + ble/widget/vi-command/search-forward + ble/widget/vi-command/search-backward + ble/widget/vi-command/search-repeat + ble/widget/vi-command/search-reverse-repeat +) +function ble/keymap:vi/register#set-edit { + ble/keymap:vi/register#set "$@" || return 1 + local reg=$1 type=$2 content=$3 + if [[ $reg == '' || $reg == 34 ]]; then + local IFS=$_ble_term_IFS + local widget=${WIDGET%%["$_ble_term_IFS"]*} + if [[ $content == *$'\n'* || " $widget " == " ${_ble_keymap_vi_register_49_widget_list[*]} " ]]; then + local n + for ((n=9;n>=2;n--)); do + _ble_keymap_vi_register[48+n]=${_ble_keymap_vi_register[48+n-1]} + done + ble/keymap:vi/register#set 49 "$type" "$content" # "1 + else + ble/keymap:vi/register#set 45 "$type" "$content" # "- + fi + fi +} +function ble/keymap:vi/register#play { + local reg=$1 value + if [[ $reg ]] && ((reg!=34)); then + value=${_ble_keymap_vi_register[reg]} + if [[ $value == */* ]]; then + value=${value#*/} + else + value= + return 1 + fi + else + value=$_ble_edit_kill_ring + fi + local _ble_keymap_vi_register_onplay=1 + local ret; ble/decode/charlog#decode "$value" + ble/widget/.MACRO "${ret[@]}" + return 0 +} +function ble/keymap:vi/register#dump/escape { + local text=$1 + local out= i=0 iN=${#text} + while ((i<iN)); do + local tail=${text:i} + if ble/util/isprint+ "$tail"; then + out=$out$BASH_REMATCH + ((i+=${#BASH_REMATCH})) + else + ble/util/s2c "$tail" + local code=$ret + if ((code<32)); then + ble/util/c2s $((code+64)) + out=$out$_ble_term_rev^$ret$_ble_term_sgr0 + elif ((code==127)); then + out=$out$_ble_term_rev^?$_ble_term_sgr0 + elif ((128<=code&&code<160)); then + ble/util/c2s $((code-64)) + out=$out${_ble_term_rev}M-^$ret$_ble_term_sgr0 + else + out=$out${tail::1} + fi + ((i++)) + fi + done + ret=$out +} +function ble/keymap:vi/register#dump { + local k ret out= + local value type content + for k in 34 "${!_ble_keymap_vi_register[@]}"; do + if ((k==34)); then + type=$_ble_edit_kill_type + content=$_ble_edit_kill_ring + else + value=${_ble_keymap_vi_register[k]} + type=${value%%/*} content=${value#*/} + fi + ble/util/c2s "$k"; k=$ret + case $type in + (L) type=line ;; + (B:*) type=block ;; + (*) type=char ;; + esac + ble/keymap:vi/register#dump/escape "$content"; content=$ret + out=$out'"'$k' ('$type') '$content$'\n' + done + ble/edit/info/show ansi "$out" + return 0 +} +function ble/widget/vi-command:reg { ble/keymap:vi/register#dump; } +function ble/widget/vi-command:regi { ble/keymap:vi/register#dump; } +function ble/widget/vi-command:regis { ble/keymap:vi/register#dump; } +function ble/widget/vi-command:regist { ble/keymap:vi/register#dump; } +function ble/widget/vi-command:registe { ble/keymap:vi/register#dump; } +function ble/widget/vi-command:register { ble/keymap:vi/register#dump; } +function ble/widget/vi-command:registers { ble/keymap:vi/register#dump; } +function ble/widget/vi-command/append-arg { + local ret ch=$1 + if [[ ! $ch ]]; then + local n=${#KEYS[@]} + local code=$((KEYS[n?n-1:0]&_ble_decode_MaskChar)) + ((code==0)) && return 1 + ble/util/c2s "$code"; ch=$ret + fi + ble/util/assert '[[ ! ${ch//[0-9]} ]]' + if [[ $ch == 0 && ! $_ble_edit_arg ]]; then + ble/widget/vi-command/beginning-of-line + return "$?" + fi + _ble_edit_arg="$_ble_edit_arg$ch" + return 0 +} +function ble/widget/vi-command/register { + _ble_decode_key__hook="ble/widget/vi-command/register.hook" +} +function ble/widget/vi-command/register.hook { + local key=$1 + ble/keymap:vi/clear-arg + local ret + if ble/keymap:vi/k2c "$key" && local c=$ret; then + if ((65<=c&&c<91)); then # A-Z + _ble_keymap_vi_reg=+$((c+32)) + return 0 + elif ((97<=c&&c<123||48<=c&&c<58||c==45||c==58||c==46||c==37||c==35||c==61||c==42||c==43||c==126||c==95||c==47)); then # a-z 0-9 - : . % # = * + ~ _ / + _ble_keymap_vi_reg=$c + return 0 + elif ((c==34)); then # "" + _ble_keymap_vi_reg=$c + return 0 + fi + fi + ble/widget/vi-command/bell + return 1 +} +_ble_keymap_vi_reg_record= +_ble_keymap_vi_reg_record_char= +_ble_keymap_vi_reg_record_play=0 +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_reg_record \ + _ble_keymap_vi_reg_record_char \ + _ble_keymap_vi_reg_record_play +function ble/widget/vi_nmap/record-register { + if [[ $_ble_keymap_vi_register_onplay ]]; then + ble/keymap:vi/clear-arg + ble/keymap:vi/adjust-command-mode + return 0 + fi + if [[ $_ble_keymap_vi_reg_record ]]; then + ble/keymap:vi/clear-arg + local -a ret + ble/decode/charlog#end-exclusive-depth1 + ble/decode/charlog#encode "${ret[@]}" + ble/keymap:vi/register#set "$_ble_keymap_vi_reg_record" q "$ret" + _ble_keymap_vi_reg_record= + ble/keymap:vi/update-mode-name + else + _ble_decode_key__hook="ble/widget/vi_nmap/record-register.hook" + fi +} +function ble/widget/vi_nmap/record-register.hook { + local key=$1 ret + ble/keymap:vi/clear-arg + local reg= c= + if ble/keymap:vi/k2c "$key" && c=$ret; then + if ((65<=c&&c<91)); then # q{A-Z} + reg=+$((c+32)) + elif ((48<=c&&c<58||97<=c&&c<123)); then # q{0-9a-z} + reg=$c + elif ((c==34)); then # q" + reg=$c + fi + fi + if [[ ! $reg ]]; then + ble/widget/vi-command/bell "invalid register key=$key" + return 1 + fi + if ! ble/decode/charlog#start vi-macro; then + ble/widget/.bell 'vi-macro: the logging system is currently busy' + return 1 + fi + ble/util/c2s "$c" + _ble_keymap_vi_reg_record=$reg + _ble_keymap_vi_reg_record_char=$ret + ble/keymap:vi/update-mode-name + return 0 +} +function ble/widget/vi_nmap/play-register { + _ble_decode_key__hook="ble/widget/vi_nmap/play-register.hook" +} +function ble/widget/vi_nmap/play-register.hook { + ble/keymap:vi/clear-arg + local depth=$_ble_keymap_vi_reg_record_play + if ((depth>=bleopt_keymap_vi_macro_depth)) || ble/util/is-stdin-ready; then + return 1 # 無限ループを防ぐため + fi + local _ble_keymap_vi_reg_record_play=$((depth+1)) + local key=$1 + local ret + if ble/keymap:vi/k2c "$key" && local c=$ret; then + ((65<=c&&c<91)) && ((c+=32)) # A-Z -> a-z + if ((48<=c&&c<58||97<=c&&c<123)); then # 0-9a-z + ble/keymap:vi/register#play "$c" && return 0 + fi + fi + ble/widget/vi-command/bell + return 1 +} +function ble/widget/vi-command/operator { + local ret opname=$1 + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + local ARG FLAG REG; ble/keymap:vi/get-arg '' + local a=$_ble_edit_ind b=$_ble_edit_mark + ((a<=b||(a=_ble_edit_mark,b=_ble_edit_ind))) + ble/widget/vi_xmap/.save-visual-state + local ble_keymap_vi_mark_active=$_ble_edit_mark_active # used in call-operator-blockwise + local mark_type=${_ble_edit_mark_active%+} + ble/widget/vi_xmap/exit + local ble_keymap_vi_opmode=$mark_type + if [[ $mark_type == vi_line ]]; then + ble/keymap:vi/call-operator-linewise "$opname" "$a" "$b" "$ARG" "$REG" + elif [[ $mark_type == vi_block ]]; then + ble/keymap:vi/call-operator-blockwise "$opname" "$a" "$b" "$ARG" "$REG" + else + local end=$b + ((end<${#_ble_edit_str}&&end++)) + ble/keymap:vi/call-operator-charwise "$opname" "$a" "$end" "$ARG" "$REG" + fi; local ext=$? + ((ext==147)) && return 147 + ((ext)) && ble/widget/.bell + ble/keymap:vi/adjust-command-mode + return "$ext" + elif [[ $_ble_decode_keymap == vi_nmap ]]; then + ble/decode/keymap/push vi_omap + _ble_keymap_vi_oparg=$_ble_edit_arg + _ble_keymap_vi_opfunc=$opname + _ble_edit_arg= + ble/keymap:vi/update-mode-name + elif [[ $_ble_decode_keymap == vi_omap ]]; then + local opname1=${_ble_keymap_vi_opfunc%%:*} + if [[ $opname == "$opname1" ]]; then + ble/widget/vi_nmap/linewise-operator "$_ble_keymap_vi_opfunc" + else + ble/keymap:vi/clear-arg + ble/widget/vi-command/bell + return 1 + fi + fi + return 0 +} +function ble/widget/vi_nmap/linewise-operator { + local opname=${1%%:*} opflags=${1#*:} + local ARG FLAG REG; ble/keymap:vi/get-arg 1 # _ble_edit_arg is consumed here + if ((ARG==1)) || [[ ${_ble_edit_str:_ble_edit_ind} == *$'\n'* ]]; then + if [[ :$opflags: == *:vi_char:* || :$opflags: == *:vi_block:* ]]; then + local beg=$_ble_edit_ind + local ret; ble-edit/content/find-logical-bol "$beg" $((ARG-1)); local end=$ret + ((beg<=end)) || local beg=$end end=$beg + if [[ :$opflags: == *:vi_block:* ]]; then + ble/keymap:vi/call-operator-blockwise "$opname" "$beg" "$end" '' "$REG" + else + ble/keymap:vi/call-operator-charwise "$opname" "$beg" "$end" '' "$REG" + fi + else + ble/keymap:vi/call-operator-linewise "$opname" "$_ble_edit_ind" "$_ble_edit_ind:$((ARG-1))" '' "$REG"; local ext=$? + fi + if ((ext==0)); then + ble/keymap:vi/adjust-command-mode + return 0 + elif ((ext==147)); then + return 147 + fi + fi + ble/widget/vi-command/bell + return 1 +} +function ble/widget/vi_nmap/copy-current-line { + ble/widget/vi_nmap/linewise-operator y +} +function ble/widget/vi_nmap/kill-current-line { + ble/widget/vi_nmap/linewise-operator d +} +function ble/widget/vi_nmap/kill-current-line-and-insert { + ble/widget/vi_nmap/linewise-operator c +} +function ble/widget/vi-command/beginning-of-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret; ble-edit/content/find-logical-bol; local beg=$ret + ble/widget/vi-command/exclusive-goto.impl "$beg" "$FLAG" "$REG" nobell +} +function ble/keymap:vi/call-operator { + ble/keymap:vi/mark/start-edit-area + local _ble_keymap_vi_mark_suppress_edit=1 + ble/keymap:vi/operator:"$@"; local ext=$? + ble/util/unlocal _ble_keymap_vi_mark_suppress_edit + ble/keymap:vi/mark/end-edit-area + if ((ext==0)); then + if ble/is-function ble/keymap:vi/operator:"$1".record; then + ble/keymap:vi/operator:"$1".record + else + ble/keymap:vi/repeat/record + fi + fi + return "$ext" +} +function ble/keymap:vi/call-operator-charwise { + local ch=$1 beg=$2 end=$3 arg=$4 reg=$5 + ((beg<=end||(beg=$3,end=$2))) + if ble/is-function ble/keymap:vi/operator:"$ch"; then + local ble_keymap_vi_operator_index= + ble/keymap:vi/call-operator "$ch" "$beg" "$end" char "$arg" "$reg"; local ext=$? + ((ext==147)) && return 147 + local index=${ble_keymap_vi_operator_index:-$beg} + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + _ble_edit_ind=$index + return 0 + else + return 1 + fi +} +function ble/keymap:vi/call-operator-linewise { + local ch=$1 a=$2 b=$3 arg=$4 reg=$5 ia=0 ib=0 + [[ $a == *:* ]] && local a=${a%%:*} ia=${a#*:} + [[ $b == *:* ]] && local b=${b%%:*} ib=${b#*:} + local ret + ble-edit/content/find-logical-bol "$a" "$ia"; local beg=$ret + ble-edit/content/find-logical-eol "$b" "$ib"; local end=$ret + if ble/is-function ble/keymap:vi/operator:"$ch"; then + local ble_keymap_vi_operator_index= + ((end<${#_ble_edit_str}&&end++)) + ble/keymap:vi/call-operator "$ch" "$beg" "$end" line "$arg" "$reg"; local ext=$? + ((ext==147)) && return 147 + if [[ $ble_keymap_vi_operator_index ]]; then + local index=$ble_keymap_vi_operator_index + else + ble-edit/content/find-logical-bol "$beg"; beg=$ret # operator 中で beg が変更されているかも + ble-edit/content/find-non-space "$beg"; local index=$ret + fi + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + _ble_edit_ind=$index + return 0 + else + return 1 + fi +} +function ble/keymap:vi/call-operator-blockwise { + local ch=$1 beg=$2 end=$3 arg=$4 reg=$5 + if ble/is-function ble/keymap:vi/operator:"$ch"; then + local mark_active=${ble_keymap_vi_mark_active:-vi_block} + local sub_ranges sub_x1 sub_x2 + _ble_edit_mark_active=$mark_active ble/keymap:vi/extract-block "$beg" "$end" + local nrange=${#sub_ranges[@]} + ((nrange)) || return 1 + local ble_keymap_vi_operator_index= + local beg=${sub_ranges[0]}; beg=${beg%%:*} + local end=${sub_ranges[nrange-1]}; end=${end#*:}; end=${end%%:*} + ble/keymap:vi/call-operator "$ch" "$beg" "$end" block "$arg" "$reg" + ((ext==147)) && return 147 + local index=${ble_keymap_vi_operator_index:-$beg} + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + _ble_edit_ind=$index + return 0 + else + return 1 + fi +} +function ble/keymap:vi/operator:d { + local context=$3 arg=$4 reg=$5 # beg end は上書きする + if [[ $context == line ]]; then + ble/keymap:vi/register#set-edit "$reg" L "${_ble_edit_str:beg:end-beg}" || return 1 + if ((end==${#_ble_edit_str}&&beg>0)); then + local ret + ((beg--)) + ble-edit/content/find-logical-bol "$beg" + ble-edit/content/find-non-space "$ret" + ble_keymap_vi_operator_index=$ret + fi + ble/widget/.delete-range "$beg" "$end" + elif [[ $context == block ]]; then + local -a afill=() atext=() arep=() + local sub shift=0 slpad0= + local smin smax slpad srpad sfill stext + for sub in "${sub_ranges[@]}"; do + stext=${sub#*:*:*:*:*:} + ble/string#split sub : "$sub" + smin=${sub[0]} smax=${sub[1]} + slpad=${sub[2]} srpad=${sub[3]} + sfill=${sub[4]} + [[ $slpad0 ]] || slpad0=$slpad # 最初の slpad + ble/array#push afill "$sfill" + ble/array#push atext "$stext" + local ret; ble/string#repeat ' ' $((slpad+srpad)) + ble/array#push arep $((smin+shift)):$((smax+shift)):"$ret" + ((shift+=(slpad+srpad)-(smax-smin))) + done + IFS=$'\n' builtin eval 'local yank_content="${atext[*]-}"' + local IFS=$_ble_term_IFS + local yank_type=B:"${afill[*]-}" + ble/keymap:vi/register#set-edit "$reg" "$yank_type" "$yank_content" || return 1 + local rep + for rep in "${arep[@]}"; do + smin=${rep%%:*}; rep=${rep:${#smin}+1} + smax=${rep%%:*}; rep=${rep:${#smax}+1} + ble/widget/.replace-range "$smin" "$smax" "$rep" + done + ((beg+=slpad)) # fix start position + else + if ((beg<end)); then + if [[ $ble_keymap_vi_opmode != vi_char && ${_ble_edit_str:beg:end-beg} == *$'\n'* ]]; then + if local rex=$'(^|\n)([ \t]*)$'; [[ ${_ble_edit_str::beg} =~ $rex ]]; then + local prefix=${BASH_REMATCH[2]} + if rex=$'^[ \t]*(\n|$)'; [[ ${_ble_edit_str:end} =~ $rex ]]; then + local suffix=$BASH_REMATCH + ((beg-=${#prefix},end+=${#suffix})) + ble/keymap:vi/operator:d "$beg" "$end" line "$arg" "$reg" + return "$?" + fi + fi + fi + ble/keymap:vi/register#set-edit "$reg" '' "${_ble_edit_str:beg:end-beg}" || return 1 + ble/widget/.delete-range "$beg" "$end" + fi + fi + return 0 +} +function ble/keymap:vi/operator:c { + local context=$3 arg=$4 reg=$5 # beg は上書き対象 + if [[ $context == line ]]; then + ble/keymap:vi/register#set-edit "$reg" L "${_ble_edit_str:beg:end-beg}" || return 1 + local end2=$end + ((end2)) && [[ ${_ble_edit_str:end2-1:1} == $'\n' ]] && ((end2--)) + local indent= ret + ble-edit/content/find-non-space "$beg"; local nol=$ret + ((beg<nol)) && indent=${_ble_edit_str:beg:nol-beg} + ble/widget/.replace-range "$beg" "$end2" "$indent" + ble/widget/vi_nmap/.insert-mode + elif [[ $context == block ]]; then + ble/keymap:vi/operator:d "$@" || return 1 # @var beg will be overwritten here + local sub=${sub_ranges[0]} + local smin=${sub%%:*} sub=${sub#*:} + local smax=${sub%%:*} sub=${sub#*:} + local slpad=${sub%%:*} sub=${sub#*:} + ((smin+=slpad,smax=smin,slpad=0)) + sub_ranges[0]=$smin:$smax:$slpad:$sub + ble/widget/vi_xmap/block-insert-mode.impl insert + else + local ble_keymap_vi_opmode=vi_char + ble/keymap:vi/operator:d "$@" || return 1 + ble/widget/vi_nmap/.insert-mode + fi + return 0 +} +function ble/keymap:vi/operator:y.record { :; } +function ble/keymap:vi/operator:y { + local beg=$1 end=$2 context=$3 arg=$4 reg=$5 + local yank_type= yank_content= + if [[ $context == line ]]; then + ble_keymap_vi_operator_index=$_ble_edit_ind # operator:y では現在位置を動かさない + yank_type=L + yank_content=${_ble_edit_str:beg:end-beg} + elif [[ $context == block ]]; then + local sub + local -a afill=() atext=() + for sub in "${sub_ranges[@]}"; do + local sub4=${sub#*:*:*:*:} + local sfill=${sub4%%:*} stext=${sub4#*:} + ble/array#push afill "$sfill" + ble/array#push atext "$stext" + done + IFS=$'\n' builtin eval 'local yank_content="${atext[*]-}"' + local IFS=$_ble_term_IFS + yank_type=B:"${afill[*]-}" + else + yank_type= + yank_content=${_ble_edit_str:beg:end-beg} + fi + ble/keymap:vi/register#set-yank "$reg" "$yank_type" "$yank_content" || return 1 + ble/keymap:vi/mark/commit-edit-area "$beg" "$end" + return 0 +} +function ble/keymap:vi/operator:tr.impl { + local beg=$1 end=$2 context=$3 filter=$4 + if [[ $context == block ]]; then + local isub=${#sub_ranges[@]} + while ((isub--)); do + ble/string#split sub : "${sub_ranges[isub]}" + local smin=${sub[0]} smax=${sub[1]} + local ret; "$filter" "${_ble_edit_str:smin:smax-smin}" + ble/widget/.replace-range "$smin" "$smax" "$ret" + done + else + local ret; "$filter" "${_ble_edit_str:beg:end-beg}" + ble/widget/.replace-range "$beg" "$end" "$ret" + fi + return 0 +} +function ble/keymap:vi/operator:u { + ble/keymap:vi/operator:tr.impl "$1" "$2" "$3" ble/string#tolower +} +function ble/keymap:vi/operator:U { + ble/keymap:vi/operator:tr.impl "$1" "$2" "$3" ble/string#toupper +} +function ble/keymap:vi/operator:toggle_case { + ble/keymap:vi/operator:tr.impl "$1" "$2" "$3" ble/string#toggle-case +} +function ble/keymap:vi/operator:rot13 { + ble/keymap:vi/operator:tr.impl "$1" "$2" "$3" ble/keymap:vi/string#encode-rot13 +} +function ble/keymap:vi/expand-range-for-linewise-operator { + local ret + ble-edit/content/find-logical-bol "$beg"; beg=$ret + ble-edit/content/find-logical-bol "$end"; local bol2=$ret + ble-edit/content/find-non-space "$bol2"; local nol2=$ret + if ((beg<bol2&&_ble_edit_ind<=bol2&&end<=nol2)); then + end=$bol2 + else + ble-edit/content/find-logical-eol "$end"; local end=$ret + [[ ${_ble_edit_str:end:1} == $'\n' ]] && ((end++)) + fi +} +function ble/keymap:vi/string#increase-indent { + local text=$1 delta=$2 + local space=$' \t' it=${bleopt_tab_width:-$_ble_term_it} + local arr; ble/string#split-lines arr "$text" + local -a arr2=() + local line indent i len x r + for line in "${arr[@]}"; do + indent=${line%%[!$space]*} + line=${line:${#indent}} + ((x=0)) + if [[ $indent ]]; then + ((len=${#indent})) + for ((i=0;i<len;i++)); do + if [[ ${indent:i:1} == ' ' ]]; then + ((x++)) + else + ((x=(x+it)/it*it)) + fi + done + fi + ((x+=delta,x<0&&(x=0))) + indent= + if ((x)); then + if ((bleopt_indent_tabs&&(r=x/it))); then + ble/string#repeat $'\t' "$r" + indent=$ret + ((x%=it)) + fi + if ((x)); then + ble/string#repeat ' ' "$x" + indent=$indent$ret + fi + fi + ble/array#push arr2 "$indent$line" + done + IFS=$'\n' builtin eval 'ret="${arr2[*]-}"' +} +function ble/keymap:vi/operator:indent.impl/increase-block-indent { + local width=$1 + local isub=${#sub_ranges[@]} + local sub smin slpad ret + while ((isub--)); do + ble/string#split sub : "${sub_ranges[isub]}" + smin=${sub[0]} slpad=${sub[2]} + ble/string#repeat ' ' $((slpad+width)) + ble/widget/.replace-range "$smin" "$smin" "$ret" + done +} +function ble/keymap:vi/operator:indent.impl/decrease-graphical-block-indent { + local width=$1 + local it=${bleopt_tab_width:-$_ble_term_it} cols=$_ble_textmap_cols + local sub smin slpad ret + local -a replaces=() + local isub=${#sub_ranges[@]} + while ((isub--)); do + ble/string#split sub : "${sub_ranges[isub]}" + smin=${sub[0]} slpad=${sub[2]} + ble-edit/content/find-non-space "$smin"; local nsp=$ret + ((smin<nsp)) || continue + local ax ay bx by + ble/textmap#getxy.out --prefix=a "$smin" + ble/textmap#getxy.out --prefix=b "$nsp" + local w=$(((bx-ax)-(by-ay)*cols-width)) + ((w<slpad)) && w=$slpad + local ins= + if ((w)); then + local r + if ((bleopt_indent_tabs&&(r=(ax+w)/it-ax/it))); then + ble/string#repeat $'\t' "$r"; ins=$ret + ((w=(ax+w)%it)) + fi + if ((w)); then + ble/string#repeat ' ' "$w" + ins=$ins$ret + fi + fi + ble/array#push replaces "$smin:$nsp:$ins" + done + local rep + for rep in "${replaces[@]}"; do + ble/string#split rep : "$rep" + ble/widget/.replace-range "${rep[@]::3}" + done +} +function ble/keymap:vi/operator:indent.impl/decrease-logical-block-indent { + local width=$1 + local it=${bleopt_tab_width:-$_ble_term_it} + local sub smin ret nsp + local isub=${#sub_ranges[@]} + while ((isub--)); do + ble/string#split sub : "${sub_ranges[isub]}" + smin=${sub[0]} + ble-edit/content/find-non-space "$smin"; nsp=$ret + ((smin<nsp)) || continue + local stext=${_ble_edit_str:smin:nsp-smin} + local i=0 n=${#stext} c=0 pad=0 + for ((i=0;i<n;i++)); do + if [[ ${stext:i:1} == $'\t' ]]; then + ((c+=it)) + else + ((c++)) + fi + if ((c>=width)); then + pad=$((c-width)) + nsp=$((smin+i+1)) + break + fi + done + local padding= + ((pad)) && { ble/string#repeat ' ' "$pad"; padding=$ret; } + ble/widget/.replace-range "$smin" "$nsp" "$padding" + done +} +function ble/keymap:vi/operator:indent.impl { + local delta=$1 context=$2 + ((delta)) || return 0 + if [[ $context == block ]]; then + if ((delta>=0)); then + ble/keymap:vi/operator:indent.impl/increase-block-indent "$delta" + elif ble/edit/use-textmap; then + ble/keymap:vi/operator:indent.impl/decrease-graphical-block-indent $((-delta)) + else + ble/keymap:vi/operator:indent.impl/decrease-logical-block-indent $((-delta)) + fi + else + [[ $context == char ]] && ble/keymap:vi/expand-range-for-linewise-operator + ((beg<end)) && [[ ${_ble_edit_str:end-1:1} == $'\n' ]] && ((end--)) + local ret + ble/keymap:vi/string#increase-indent "${_ble_edit_str:beg:end-beg}" "$delta"; local content=$ret + ble/widget/.replace-range "$beg" "$end" "$content" + if [[ $context == char ]]; then + ble-edit/content/find-non-space "$beg" + ble_keymap_vi_operator_index=$ret + fi + fi + return 0 +} +function ble/keymap:vi/operator:indent-left { + local context=$3 arg=${4:-1} + ble/keymap:vi/operator:indent.impl $((-bleopt_indent_offset*arg)) "$context" +} +function ble/keymap:vi/operator:indent-right { + local context=$3 arg=${4:-1} + ble/keymap:vi/operator:indent.impl $((bleopt_indent_offset*arg)) "$context" +} +function ble/keymap:vi/string#measure-width { + local text=$1 iN=${#1} i=0 s=0 + while ((i<iN)); do + if ble/util/isprint+ "${text:i}"; then + ((s+=${#BASH_REMATCH}, + i+=${#BASH_REMATCH})) + else + ble/util/s2c "${text:i:1}" + ble/util/c2w-edit "$ret" + ((s+=ret,i++)) + fi + done + ret=$s +} +function ble/keymap:vi/string#fold/.get-interval { + local text=$1 x=$2 + local it=${bleopt_tab_width:-${_ble_term_it:-8}} + local i=0 iN=${#text} + for ((i=0;i<iN;i++)); do + if [[ ${text:i:1} == $'\t' ]]; then + ((x=(x/it+1)*it)) + else + ((x++)) + fi + done + ret=$((x-$2)) +} +function ble/keymap:vi/string#fold { + local text=$1 + local cols=${2:-${COLUMNS-80}} + local sp=$' \t' nl=$'\n' + local i=0 out= otmp= x=0 xtmp=0 + local isfirst=1 indent= xindent=0 + local rex='^([^'$nl$sp']+)|^(['$sp']+)|^.' + while [[ ${text:i} =~ $rex ]]; do + ((i+=${#BASH_REMATCH})) + if [[ ${BASH_REMATCH[1]} ]]; then + local word=${BASH_REMATCH[1]} + ble/keymap:vi/string#measure-width "$word" + if ((xtmp+ret<cols||xtmp<=xindent)); then + out=$out$otmp$word + ((x=xtmp+=ret)) + else + out=$out$'\n'$indent$word + ((x=xtmp=xindent+ret)) + fi + otmp= + else + local w=1 + if [[ ${BASH_REMATCH[2]} ]]; then + [[ $otmp ]] && continue # 改行直後の空白は無視 + otmp=${BASH_REMATCH[2]} + ble/keymap:vi/string#fold/.get-interval "$otmp" "$x"; w=$ret + [[ $isfirst ]] && indent=$otmp xindent=$ret # インデント記録 + else + otmp=' ' w=1 + fi + if ((x+w<cols)); then + ((xtmp=x+w)) + else + ((xtmp=xindent)) + otmp=$'\n'$indent + fi + fi + isfirst= + done + ret=$out +} +function ble/keymap:vi/operator:fold/.fold-paragraphwise { + local text=$1 + local cols=${2:-${COLUMNS:-80}} + local nl=$'\n' sp=$' \t' + local rex_paragraph='^((['$sp']*'$nl')*)(['$sp']*[^'$sp$nl'][^'$nl']*('$nl'|$))+' + local i=0 out= + while [[ ${text:i} =~ $rex_paragraph ]]; do + ((i+=${#BASH_REMATCH})) + local rematch1=${BASH_REMATCH[1]} + local len1=${#rematch1} + local paragraph=${BASH_REMATCH:len1} + ble/keymap:vi/string#fold "$paragraph" "$cols" + paragraph=${ret%$'\n'}$'\n' + out=$out$rematch1$paragraph + done + ret=$out${text:i} +} +function ble/keymap:vi/operator:fold.impl { + local context=$1 opts=$2 + local ret + [[ $context != line ]] && ble/keymap:vi/expand-range-for-linewise-operator + local old=${_ble_edit_str:beg:end-beg} oind=$_ble_edit_ind + local cols=${COLUMNS:-80}; ((cols>80&&(cols=80))) + ble/keymap:vi/operator:fold/.fold-paragraphwise "$old" "$cols"; local new=$ret + ble/widget/.replace-range "$beg" "$end" "$new" + if [[ :$opts: == *:preserve_point:* ]]; then + if ((end<=oind)); then + ble_keymap_vi_operator_index=$((beg+${#new})) + elif ((beg<oind)); then + ble/keymap:vi/operator:fold/.fold-paragraphwise "${old::oind-beg}" "$cols" + ble_keymap_vi_operator_index=$((beg+${#ret})) + fi + else + if [[ $new ]]; then + ble-edit/content/find-logical-bol $((beg+${#new}-1)) + ble-edit/content/find-non-space "$ret" + ble_keymap_vi_operator_index=$ret + fi + fi + return 0 +} +function ble/keymap:vi/operator:fold { + local context=$3 + ble/keymap:vi/operator:fold.impl "$context" +} +function ble/keymap:vi/operator:fold-preserve-point { + local context=$3 + ble/keymap:vi/operator:fold.impl "$context" preserve_point +} +_ble_keymap_vi_filter_args=() +_ble_keymap_vi_filter_repeat=() +_ble_keymap_vi_filter_history=() +_ble_keymap_vi_filter_history_edit=() +_ble_keymap_vi_filter_history_dirt=() +_ble_keymap_vi_filter_history_index=0 +function ble/highlight/layer:region/mark:vi_filter/get-face { + face=region_target +} +function ble/keymap:vi/operator:filter/.cache-repeat { + local -a _ble_keymap_vi_repeat _ble_keymap_vi_repeat_irepeat + ble/keymap:vi/repeat/record-normal + _ble_keymap_vi_filter_repeat=("${_ble_keymap_vi_repeat[@]}") +} +function ble/keymap:vi/operator:filter/.record-repeat { + ble/keymap:vi/repeat/record-special && return 0 + local command=$1 + _ble_keymap_vi_repeat=("${_ble_keymap_vi_filter_repeat[@]}") + _ble_keymap_vi_repeat_irepeat=() + _ble_keymap_vi_repeat[10]=$command +} +function ble/keymap:vi/operator:filter { + local context=$3 + [[ $context != line ]] && ble/keymap:vi/expand-range-for-linewise-operator + _ble_keymap_vi_filter_args=("$beg" "$end" "${@:3}") + if [[ $_ble_keymap_vi_repeat_invoke ]]; then + local command=${_ble_keymap_vi_repeat[10]} + ble/keymap:vi/operator:filter/.hook "$command" + return "$?" + else + ble/keymap:vi/operator:filter/.cache-repeat + _ble_edit_ind=$beg + _ble_edit_mark=$end + _ble_edit_mark_active=vi_filter + ble/keymap:vi/async-commandline-mode 'ble/keymap:vi/operator:filter/.hook' + _ble_edit_PS1='!' + ble/history/set-prefix _ble_keymap_vi_filter + _ble_keymap_vi_cmap_before_command=ble/keymap:vi/commandline/before-command.hook + _ble_keymap_vi_cmap_cancel_hook=ble/keymap:vi/operator:filter/cancel.hook + _ble_syntax_lang=bash + _ble_highlight_layer__list=(plain syntax region overwrite_mode) + return 147 + fi +} +function ble/keymap:vi/operator:filter/cancel.hook { + _ble_edit_mark_active= # clear mark:vi_filter +} +function ble/keymap:vi/operator:filter/.hook { + local command=$1 # 入力されたコマンド + if [[ ! $command ]]; then + ble/widget/vi-command/bell + return 1 + fi + local beg=${_ble_keymap_vi_filter_args[0]} + local end=${_ble_keymap_vi_filter_args[1]} + local context=${_ble_keymap_vi_filter_args[2]} + _ble_edit_mark_active= # clear mark:vi_filter + local old=${_ble_edit_str:beg:end-beg} new + old=${old%$'\n'} + if ! ble/util/assign new 'builtin eval -- "$command" <<< "$old" 2>/dev/null'; then + ble/widget/vi-command/bell + return 1 + fi + new=${new%$'\n'}$'\n' + ble/widget/.replace-range "$beg" "$end" "$new" + _ble_edit_ind=$beg + if [[ $context == line ]]; then + ble/widget/vi-command/first-non-space + else + ble/keymap:vi/adjust-command-mode + fi + ble/keymap:vi/mark/set-previous-edit-area "$beg" $((beg+${#new})) + ble/keymap:vi/operator:filter/.record-repeat "$command" + return 0 +} +bleopt/declare -v keymap_vi_operatorfunc '' +function ble/keymap:vi/operator:map { + local context=$3 + if [[ $bleopt_keymap_vi_operatorfunc ]]; then + local opfunc=ble/keymap:vi/operator:$bleopt_keymap_vi_operatorfunc + if ble/is-function "$opfunc"; then + "$opfunc" "$@" + return "$?" + fi + fi + return 1 +} +function ble/widget/vi-command/exclusive-range.impl { + local src=$1 dst=$2 flag=$3 reg=$4 opts=$5 + if [[ $flag ]]; then + local opname=${flag%%:*} opflags=${flag#*:} + if [[ :$opflags: == *:vi_line:* ]]; then + local ble_keymap_vi_opmode=vi_line + ble/keymap:vi/call-operator-linewise "$opname" "$src" "$dst" '' "$reg"; local ext=$? + elif [[ :$opflags: == *:vi_block:* ]]; then + local ble_keymap_vi_opmode=vi_line + ble/keymap:vi/call-operator-blockwise "$opname" "$src" "$dst" '' "$reg"; local ext=$? + elif [[ :$opflags: == *:vi_char:* ]]; then + local ble_keymap_vi_opmode=vi_char + if [[ :$opts: == *:inclusive:* ]]; then + ((src<dst?dst--:(dst<src&&src--))) + else + if ((src<=dst)); then + ((dst<${#_ble_edit_str})) && + [[ ${_ble_edit_str:dst:1} != $'\n' ]] && + ((dst++)) + else + ((src<${#_ble_edit_str})) && + [[ ${_ble_edit_str:src:1} != $'\n' ]] && + ((src++)) + fi + fi + ble/keymap:vi/call-operator-charwise "$opname" "$src" "$dst" '' "$reg"; local ext=$? + else + local ble_keymap_vi_opmode= + ble/keymap:vi/call-operator-charwise "$opname" "$src" "$dst" '' "$reg"; local ext=$? + fi + ((ext==147)) && return 147 + ((ext)) && ble/widget/.bell + ble/keymap:vi/adjust-command-mode + return "$ext" + else + ble/keymap:vi/needs-eol-fix "$dst" && ((dst--)) + if ((dst!=_ble_edit_ind)); then + _ble_edit_ind=$dst + elif [[ :$opts: != *:nobell:* ]]; then + ble/widget/vi-command/bell + return 1 + fi + ble/keymap:vi/adjust-command-mode + return 0 + fi +} +function ble/widget/vi-command/exclusive-goto.impl { + local index=$1 flag=$2 reg=$3 opts=$4 + if [[ $flag ]]; then + if ble-edit/content/bolp "$index"; then + local is_linewise= + if ((_ble_edit_ind<index)); then + ((index--)) + rex=$'(^|\n)[ \t]*$' + [[ ${_ble_edit_str::_ble_edit_ind} =~ $rex ]] && + is_linewise=1 + elif ((index<_ble_edit_ind)); then + ble-edit/content/bolp && + is_linewise=1 + fi + if [[ $is_linewise ]]; then + ble/widget/vi-command/linewise-goto.impl "$index" "$flag" "$reg" + return "$?" + fi + fi + fi + ble/widget/vi-command/exclusive-range.impl "$_ble_edit_ind" "$index" "$flag" "$reg" "$opts" +} +function ble/widget/vi-command/inclusive-goto.impl { + local index=$1 flag=$2 reg=$3 opts=$4 + if [[ $flag ]]; then + if ((_ble_edit_ind<=index)); then + ble-edit/content/eolp "$index" || ((index++)) + else + ble-edit/content/eolp || ((_ble_edit_ind++)) + fi + fi + ble/widget/vi-command/exclusive-range.impl "$_ble_edit_ind" "$index" "$flag" "$reg" "$opts:inclusive" +} +function ble/widget/vi-command/linewise-range.impl { + local p=$1 q=$2 flag=$3 reg=$4 opts=$5 + local ret + if [[ $q == *:* ]]; then + local qbase=${q%%:*} qline=${q#*:} + else + local qbase=$q qline=0 + fi + local bolx=; local rex=':bolx=([0-9]+):'; [[ :$opts: =~ $rex ]] && bolx=${BASH_REMATCH[1]} + local nolx=; local rex=':nolx=([0-9]+):'; [[ :$opts: =~ $rex ]] && nolx=${BASH_REMATCH[1]} + if [[ ! $flag ]]; then + if [[ ! $nolx ]]; then + if [[ ! $bolx ]]; then + ble-edit/content/find-logical-bol "$qbase" "$qline"; bolx=$ret + fi + ble-edit/content/find-non-space "$bolx"; nolx=$ret + fi + ble-edit/content/nonbol-eolp "$nolx" && ((nolx--)) + _ble_edit_ind=$nolx + ble/keymap:vi/adjust-command-mode + return 0 + fi + local opname=${flag%%:*} opflags=${flag#*:} + if ! ble/is-function ble/keymap:vi/operator:"$opname"; then + ble/widget/vi-command/bell + return 1 + fi + local bolp bolq=$bolx nolq=$nolx + ble-edit/content/find-logical-bol "$p"; bolp=$ret + [[ $bolq ]] || { ble-edit/content/find-logical-bol "$qbase" "$qline"; bolq=$ret; } + if [[ :$opts: == *:require_multiline:* ]]; then + if ((bolq==bolp)); then + ble/widget/vi-command/bell + return 1 + fi + fi + if [[ :$opflags: == *:vi_char:* || :$opflags: == *:vi_block:* ]]; then + local beg=$p end + if [[ :$opts: == *:preserve_column:* ]]; then + local index + ble/keymap:vi/get-index-of-relative-line "$qbase" "$qline"; end=$index + elif [[ :$opts: == *:goto_bol:* ]]; then + end=$bolq + else + [[ $nolq ]] || { ble-edit/content/find-non-space "$bolq"; nolq=$ret; } + end=$nolq + fi + ((beg<=end)) || local beg=$end end=$beg + if [[ :$opflags: == *:vi_block:* ]]; then + local ble_keymap_vi_opmode=vi_block + ble/keymap:vi/call-operator "$opname" "$beg" "$end" block '' "$reg"; local ext=$? + else + local ble_keymap_vi_opmode=vi_char + ble/keymap:vi/call-operator "$opname" "$beg" "$end" char '' "$reg"; local ext=$? + fi + if ((ext)); then + ((ext==147)) && return 147 + ble/widget/vi-command/bell + return "$ext" + fi + else + local beg end + if ((bolp<=bolq)); then + ble-edit/content/find-logical-eol "$bolq"; beg=$bolp end=$ret + else + ble-edit/content/find-logical-eol "$bolp"; beg=$bolq end=$ret + fi + ((end<${#_ble_edit_str}&&end++)) + local ble_keymap_vi_opmode= + [[ :$opflags: == *:vi_line:* ]] && ble_keymap_vi_opmode=vi_line + ble/keymap:vi/call-operator "$opname" "$beg" "$end" line '' "$reg"; local ext=$? + if ((ext)); then + ((ext==147)) && return 147 + ble/widget/vi-command/bell + return "$ext" + fi + local ind=$_ble_edit_ind + if [[ $opname == [cd] ]]; then + _ble_edit_ind=$beg + ble/widget/vi-command/first-non-space + elif [[ :$opts: == *:preserve_column:* ]]; then # j k + if ((beg<ind)); then + ble/string#count-char "${_ble_edit_str:beg:ind-beg}" $'\n' + ((ret=-ret)) + elif ((ind<beg)); then + ble/string#count-char "${_ble_edit_str:ind:beg-ind}" $'\n' + else + ret=0 + fi + if ((ret)); then + local index; ble/keymap:vi/get-index-of-relative-line "$_ble_edit_ind" "$ret" + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + _ble_edit_ind=$index + fi + elif [[ :$opts: == *:goto_bol:* ]]; then # 行指向 yis + _ble_edit_ind=$beg + else # + - gg G L H + if ((beg==bolq||ind<beg)) || [[ ${_ble_edit_str:beg:ind-beg} == *$'\n'* ]] ; then + if ((bolq<=bolp)) && [[ $nolq ]]; then + local nolb=$nolq + else + ble-edit/content/find-non-space "$beg"; local nolb=$ret + fi + ble-edit/content/nonbol-eolp "$nolb" && ((nolb--)) + ((ind<beg||nolb<ind)) && _ble_edit_ind=$nolb + fi + fi + fi + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-command/linewise-goto.impl { + ble/widget/vi-command/linewise-range.impl "$_ble_edit_ind" "$@" +} +function ble/keymap:vi/async-read-char.hook { + local IFS=$_ble_term_IFS + local command="${*:1:$#-1}" key="${*:$#}" + if ((key==(_ble_decode_Ctrl|0x6B))); then # C-k + ble/decode/keymap/push vi_digraph + _ble_keymap_vi_digraph__hook="$command" + else + builtin eval -- "$command $key" + fi +} +function ble/keymap:vi/async-read-char { + local IFS=$_ble_term_IFS + _ble_decode_key__hook="ble/keymap:vi/async-read-char.hook $*" + return 147 +} +_ble_keymap_vi_mark_Offset=32 +_ble_keymap_vi_mark_hindex= +_ble_keymap_vi_mark_local=() +_ble_keymap_vi_mark_global=() +_ble_keymap_vi_mark_history=() +_ble_keymap_vi_mark_edit_dbeg=-1 +_ble_keymap_vi_mark_edit_dend=-1 +_ble_keymap_vi_mark_edit_dend0=-1 +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_mark_hindex \ + _ble_keymap_vi_mark_local \ + _ble_keymap_vi_mark_global \ + _ble_keymap_vi_mark_history \ + _ble_keymap_vi_mark_edit_dbeg \ + _ble_keymap_vi_mark_edit_dend \ + _ble_keymap_vi_mark_edit_dend0 +ble/array#push _ble_edit_dirty_observer ble/keymap:vi/mark/shift-by-dirty-range +blehook history_onleave+=ble/keymap:vi/mark/history-onleave.hook +function ble/keymap:vi/mark/history-onleave.hook { + if [[ $_ble_decode_keymap == vi_[inoxs]map ]]; then + ble/keymap:vi/mark/set-local-mark 34 "$_ble_edit_ind" # `" + fi +} +function ble/keymap:vi/mark/update-mark-history { + local h; ble/history/get-index -v h + if [[ ! $_ble_keymap_vi_mark_hindex ]]; then + _ble_keymap_vi_mark_hindex=$h + elif ((_ble_keymap_vi_mark_hindex!=h)); then + local imark value + local -a save=() + for imark in "${!_ble_keymap_vi_mark_local[@]}"; do + local value=${_ble_keymap_vi_mark_local[imark]} + ble/array#push save "$imark:$value" + done + local IFS=$_ble_term_IFS + _ble_keymap_vi_mark_history[_ble_keymap_vi_mark_hindex]="${save[*]-}" + _ble_keymap_vi_mark_local=() + local entry + for entry in ${_ble_keymap_vi_mark_history[h]-}; do + imark=${entry%%:*} value=${entry#*:} + _ble_keymap_vi_mark_local[imark]=$value + done + _ble_keymap_vi_mark_hindex=$h + fi +} +blehook history_clear+=ble/keymap:vi/mark/history-clear.hook +blehook history_delete+=ble/keymap:vi/mark/history-delete.hook +blehook history_insert+=ble/keymap:vi/mark/history-insert.hook +function ble/keymap:vi/mark/history-clear.hook { + _ble_keymap_vi_mark_global=() + _ble_keymap_vi_mark_history=() + _ble_keymap_vi_mark_hindex= +} +function ble/keymap:vi/mark/history-delete.hook { + for imark in "${!_ble_keymap_vi_mark_global[@]}"; do + local value=${_ble_keymap_vi_mark_global[imark]} + local h=${value%%:*} v=${value#*:} + local idel shift=0 + for idel; do + if [[ $idel == *-* ]]; then + local b=${idel%-*} e=${idel#*-} + ((b<=h&&h<e)) && shift= # delete + ((h<e)) && break + ((shift+=e-b)) + else + ((idel==h)) && shift= # delete + ((idel>=h)) && break + ((shift++)) + fi + done + [[ $shift ]] && + _ble_keymap_vi_mark_global[imark]=$((h-shift)):$v + done + ble/builtin/history/array#delete-hindex _ble_keymap_vi_mark_history "$@" + _ble_keymap_vi_mark_hindex= +} +function ble/keymap:vi/mark/history-insert.hook { + local beg=$1 len=$2 + for imark in "${!_ble_keymap_vi_mark_global[@]}"; do + local value=${_ble_keymap_vi_mark_global[imark]} + local h=${value%%:*} v=${value#*:} + ((h>=beg)) && _ble_keymap_vi_mark_global[imark]=$((h+len)):$v + done + ble/builtin/history/array#insert-range _ble_keymap_vi_mark_history "$@" + _ble_keymap_vi_mark_hindex= +} +function ble/keymap:vi/mark/shift-by-dirty-range { + local beg=$1 end=$2 end0=$3 reason=$4 + if [[ $4 == edit ]]; then + ble/dirty-range#update --prefix=_ble_keymap_vi_mark_edit_d "${@:1:3}" + ble/keymap:vi/xmap/update-dirty-range "$@" + ble/keymap:vi/mark/update-mark-history + local shift=$((end-end0)) + local imark + for imark in "${!_ble_keymap_vi_mark_local[@]}"; do + local value=${_ble_keymap_vi_mark_local[imark]} + local index=${value%%:*} rest=${value#*:} + ((index<beg)) || _ble_keymap_vi_mark_local[imark]=$((index<end0?beg:index+shift)):$rest + done + local h; ble/history/get-index -v h + for imark in "${!_ble_keymap_vi_mark_global[@]}"; do + local value=${_ble_keymap_vi_mark_global[imark]} + [[ $value == "$h":* ]] || continue + local h=${value%%:*}; value=${value:${#h}+1} + local index=${value%%:*}; value=${value:${#index}+1} + ((index<beg)) || _ble_keymap_vi_mark_global[imark]=$h:$((index<end0?beg:index+shift)):$value + done + ble/keymap:vi/mark/set-local-mark 46 "$beg" # `. + else + ble/dirty-range#clear --prefix=_ble_keymap_vi_mark_edit_d + if [[ $4 == newline && $_ble_decode_keymap != vi_cmap ]]; then + ble/keymap:vi/mark/set-local-mark 96 0 # `` + fi + fi +} +function ble/keymap:vi/mark/set-global-mark { + local c=$1 index=$2 ret + ble/keymap:vi/mark/update-mark-history + ble-edit/content/find-logical-bol "$index"; local bol=$ret + local h; ble/history/get-index -v h + _ble_keymap_vi_mark_global[c]=$h:$bol:$((index-bol)) +} +function ble/keymap:vi/mark/set-local-mark { + local c=$1 index=$2 ret + ble/keymap:vi/mark/update-mark-history + ble-edit/content/find-logical-bol "$index"; local bol=$ret + _ble_keymap_vi_mark_local[c]=$bol:$((index-bol)) +} +function ble/keymap:vi/mark/get-mark.impl { + local index=$1 bytes=$2 + local len=${#_ble_edit_str} + ((index>len&&(index=len))) + ble-edit/content/find-logical-bol "$index"; index=$ret + ble-edit/content/find-logical-eol "$index"; local eol=$ret + ((index+=bytes,index>eol&&(index=eol))) # ToDo: calculate by byte offset + ret=$index + return 0 +} +function ble/keymap:vi/mark/get-local-mark { + local c=$1 + ble/keymap:vi/mark/update-mark-history + local value=${_ble_keymap_vi_mark_local[c]} + [[ $value ]] || return 1 + local data + ble/string#split data : "$value" + ble/keymap:vi/mark/get-mark.impl "${data[0]}" "${data[1]}" # -> ret +} +_ble_keymap_vi_mark_suppress_edit= +function ble/keymap:vi/mark/set-previous-edit-area { + [[ $_ble_keymap_vi_mark_suppress_edit ]] && return 0 + local beg=$1 end=$2 + ((beg<end)) && ! ble-edit/content/bolp "$end" && ((end--)) + ble/keymap:vi/mark/set-local-mark 91 "$beg" # `[ + ble/keymap:vi/mark/set-local-mark 93 "$end" # `] + ble/keymap:vi/undo/add +} +function ble/keymap:vi/mark/start-edit-area { + [[ $_ble_keymap_vi_mark_suppress_edit ]] && return 0 + ble/dirty-range#clear --prefix=_ble_keymap_vi_mark_edit_d +} +function ble/keymap:vi/mark/commit-edit-area { + local beg=$1 end=$2 + ble/dirty-range#update --prefix=_ble_keymap_vi_mark_edit_d "$beg" "$end" "$end" +} +function ble/keymap:vi/mark/end-edit-area { + [[ $_ble_keymap_vi_mark_suppress_edit ]] && return 0 + local beg=$_ble_keymap_vi_mark_edit_dbeg + local end=$_ble_keymap_vi_mark_edit_dend + ((beg>=0)) && ble/keymap:vi/mark/set-previous-edit-area "$beg" "$end" +} +function ble/keymap:vi/mark/set-jump { + ble/keymap:vi/mark/set-local-mark 96 "$_ble_edit_ind" +} +function ble/widget/vi-command/set-mark { + _ble_decode_key__hook="ble/widget/vi-command/set-mark.hook" + return 147 +} +function ble/widget/vi-command/set-mark.hook { + local key=$1 + ble/keymap:vi/clear-arg + local ret + if ble/keymap:vi/k2c "$key" && local c=$ret; then + if ((65<=c&&c<91)); then # A-Z + ble/keymap:vi/mark/set-global-mark "$c" "$_ble_edit_ind" + ble/keymap:vi/adjust-command-mode + return 0 + elif ((97<=c&&c<123||c==91||c==93||c==60||c==62||c==96||c==39)); then # a-z [ ] < > ` ' + ((c==39)) && c=96 # m' は m` に読み替える + ble/keymap:vi/mark/set-local-mark "$c" "$_ble_edit_ind" + ble/keymap:vi/adjust-command-mode + return 0 + fi + fi + ble/widget/vi-command/bell + return 1 +} +function ble/widget/vi-command/goto-mark.impl { + local index=$1 flag=$2 reg=$3 opts=$4 + [[ $flag ]] || ble/keymap:vi/mark/set-jump # `` + if [[ :$opts: == *:line:* ]]; then + ble/widget/vi-command/linewise-goto.impl "$index" "$flag" "$reg" + else + ble/widget/vi-command/exclusive-goto.impl "$index" "$flag" "$reg" nobell + fi +} +function ble/widget/vi-command/goto-local-mark.impl { + local c=$1 opts=$2 ret + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + if ble/keymap:vi/mark/get-local-mark "$c" && local index=$ret; then + ble/widget/vi-command/goto-mark.impl "$index" "$FLAG" "$REG" "$opts" + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi-command/goto-global-mark.impl { + local c=$1 opts=$2 + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/keymap:vi/mark/update-mark-history + local value=${_ble_keymap_vi_mark_global[c]} + if [[ ! $value ]]; then + ble/widget/vi-command/bell + return 1 + fi + local data + ble/string#split data : "$value" + local index; ble/history/get-index + if ((index!=data[0])); then + if [[ $FLAG ]]; then + ble/widget/vi-command/bell + return 1 + fi + ble-edit/history/goto "${data[0]}" + fi + local ret + ble/keymap:vi/mark/get-mark.impl "${data[1]}" "${data[2]}" + ble/widget/vi-command/goto-mark.impl "$ret" "$FLAG" "$REG" "$opts" +} +function ble/widget/vi-command/goto-mark { + _ble_decode_key__hook="ble/widget/vi-command/goto-mark.hook ${1:-char}" + return 147 +} +function ble/widget/vi-command/goto-mark.hook { + local opts=$1 key=$2 + local ret + if ble/keymap:vi/k2c "$key" && local c=$ret; then + if ((65<=c&&c<91)); then # A-Z + ble/widget/vi-command/goto-global-mark.impl "$c" "$opts" + return "$?" + elif ((_ble_keymap_vi_mark_Offset<=c)); then + ((c==39)) && c=96 # `' は `` に読み替える + ble/widget/vi-command/goto-local-mark.impl "$c" "$opts" + return "$?" + fi + fi + ble/keymap:vi/clear-arg + ble/widget/vi-command/bell + return 1 +} +_ble_keymap_vi_repeat=() +_ble_keymap_vi_repeat_insert=() +_ble_keymap_vi_repeat_irepeat=() +_ble_keymap_vi_repeat_invoke= +function ble/keymap:vi/repeat/record-special { + [[ $_ble_keymap_vi_mark_suppress_edit ]] && return 0 + if [[ $_ble_keymap_vi_repeat_invoke ]]; then + [[ $repeat_arg ]] && _ble_keymap_vi_repeat[3]=$repeat_arg + [[ ! ${_ble_keymap_vi_repeat[5]} ]] && _ble_keymap_vi_repeat[5]=$repeat_reg + return 0 + fi + return 1 +} +function ble/keymap:vi/repeat/record-normal { + local IFS=$_ble_term_IFS + local -a repeat; repeat=("$KEYMAP" "${KEYS[*]-}" "$WIDGET" "$ARG" "$FLAG" "$REG" '') + if [[ $KEYMAP == vi_[xs]map ]]; then + repeat[6]=$_ble_keymap_vi_xmap_prev_edit + fi + if [[ $_ble_decode_keymap == vi_imap ]]; then + _ble_keymap_vi_repeat_insert=("${repeat[@]}") + else + _ble_keymap_vi_repeat=("${repeat[@]}") + _ble_keymap_vi_repeat_irepeat=() + fi +} +function ble/keymap:vi/repeat/record { + ble/keymap:vi/repeat/record-special && return 0 + ble/keymap:vi/repeat/record-normal +} +function ble/keymap:vi/repeat/record-insert { + ble/keymap:vi/repeat/record-special && return 0 + if [[ ${_ble_keymap_vi_repeat_insert-} ]]; then + _ble_keymap_vi_repeat=("${_ble_keymap_vi_repeat_insert[@]}") + _ble_keymap_vi_repeat_irepeat=("${_ble_keymap_vi_irepeat[@]}") + elif ((${#_ble_keymap_vi_irepeat[@]})); then + local IFS=$_ble_term_IFS + _ble_keymap_vi_repeat=(vi_nmap "${KEYS[*]-}" ble/widget/vi_nmap/insert-mode 1 '' '') + _ble_keymap_vi_repeat_irepeat=("${_ble_keymap_vi_irepeat[@]}") + fi + ble/keymap:vi/repeat/clear-insert +} +function ble/keymap:vi/repeat/clear-insert { + _ble_keymap_vi_repeat_insert=() +} +function ble/keymap:vi/repeat/invoke { + local repeat_arg=$_ble_edit_arg + local repeat_reg=$_ble_keymap_vi_reg + local KEYMAP=${_ble_keymap_vi_repeat[0]} + local -a KEYS; ble/string#split-words KEYS "${_ble_keymap_vi_repeat[1]}" + local WIDGET=${_ble_keymap_vi_repeat[2]} + if [[ $KEYMAP != vi_[onxs]map ]]; then + ble/widget/vi-command/bell + return 1 + elif [[ $KEYMAP == vi_omap ]]; then + ble/decode/keymap/push vi_omap + elif [[ $KEYMAP == vi_[xs]map ]]; then + local _ble_keymap_vi_xmap_prev_edit=${_ble_keymap_vi_repeat[6]} + ble/widget/vi_xmap/.restore-visual-state + ble/decode/keymap/push "$KEYMAP" + fi + _ble_edit_arg= + _ble_keymap_vi_oparg=${_ble_keymap_vi_repeat[3]} + _ble_keymap_vi_opfunc=${_ble_keymap_vi_repeat[4]} + [[ $repeat_arg ]] && _ble_keymap_vi_oparg=$repeat_arg + local REG=${_ble_keymap_vi_repeat[5]} + [[ $REG ]] && _ble_keymap_vi_reg=$REG + local _ble_keymap_vi_single_command{,_overwrite}= # single-command-mode は持続させる。 + local _ble_keymap_vi_repeat_invoke=1 + local LASTWIDGET=$_ble_decode_widget_last + _ble_decode_widget_last=$WIDGET + builtin eval -- "$WIDGET" + if [[ $_ble_decode_keymap == vi_imap ]]; then + ((_ble_keymap_vi_irepeat_count<=1?(_ble_keymap_vi_irepeat_count=2):_ble_keymap_vi_irepeat_count++)) + local -a _ble_keymap_vi_irepeat + _ble_keymap_vi_irepeat=("${_ble_keymap_vi_repeat_irepeat[@]}") + ble/array#push _ble_keymap_vi_irepeat '0:ble/widget/dummy' # Note: normal-mode が自分自身を pop しようとするので。 + ble/widget/vi_imap/normal-mode + fi + ble/util/unlocal _ble_keymap_vi_single_command{,_overwrite} +} +function ble/widget/vi_nmap/repeat { + ble/keymap:vi/repeat/invoke + ble/keymap:vi/adjust-command-mode +} +function ble/widget/vi-command/forward-char { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local index + if [[ $1 == wrap ]]; then + if [[ $FLAG || $_ble_decode_keymap == vi_[xs]map ]]; then + ((index=_ble_edit_ind+ARG, + index>${#_ble_edit_str}&&(index=${#_ble_edit_str}))) + else + local nl=$'\n' + local rex="^([^$nl]$nl?|$nl){0,$ARG}" + [[ ${_ble_edit_str:_ble_edit_ind} =~ $rex ]] + ((index=_ble_edit_ind+${#BASH_REMATCH})) + fi + else + local line=${_ble_edit_str:_ble_edit_ind:ARG} + line=${line%%$'\n'*} + ((index=_ble_edit_ind+${#line})) + fi + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" +} +function ble/widget/vi-command/backward-char { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local index + ((ARG>_ble_edit_ind&&(ARG=_ble_edit_ind))) + if [[ $1 == wrap ]]; then + if [[ $FLAG || $_ble_decode_keymap == vi_[xs]map ]]; then + ((index=_ble_edit_ind-ARG,index<0&&(index=0))) + else + local width=$ARG line + while ((width<=_ble_edit_ind)); do + line=${_ble_edit_str:_ble_edit_ind-width:width} + line=${line//[!$'\n']$'\n'/x} + ((${#line}>=ARG)) && break + ((width+=ARG-${#line})) + done + ((index=_ble_edit_ind-width,index<0&&(index=0))) + fi + else + local line=${_ble_edit_str:_ble_edit_ind-ARG:ARG} + line=${line##*$'\n'} + ((index=_ble_edit_ind-${#line})) + fi + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" +} +function ble/widget/vi_nmap/forward-char-toggle-case { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local line=${_ble_edit_str:_ble_edit_ind:ARG} + line=${line%%$'\n'*} + local len=${#line} + if ((len==0)); then + ble/widget/vi-command/bell + return 1 + fi + local index=$((_ble_edit_ind+len)) + local ret; ble/string#toggle-case "${_ble_edit_str:_ble_edit_ind:len}" + ble/widget/.replace-range "$_ble_edit_ind" "$index" "$ret" + ble/keymap:vi/mark/set-previous-edit-area "$_ble_edit_ind" "$index" + ble/keymap:vi/repeat/record + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + _ble_edit_ind=$index + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-command/.history-relative-line { + local offset=$1 + ((offset)) || return 0 + if [[ ! $_ble_history_prefix && ! $_ble_history_load_done ]]; then + ((offset<0)) || return 1 + ble/history/initialize # to use ble/history/get-index + fi + local index histsize + ble/history/get-index + ble/history/get-count -v histsize + local ret count=$((offset<0?-offset:offset)) exit=1 + ((count--)) + while ((count>=0)); do + if ((offset<0)); then + ((index>0)) || return "$exit" + ble/widget/history-prev + ret=${#_ble_edit_str} + ble/keymap:vi/needs-eol-fix "$ret" && ((ret--)) + _ble_edit_ind=$ret + else + ((index<histsize)) || return "$exit" + ble/widget/history-next + _ble_edit_ind=0 + fi + exit=0 + ble/string#count-char "$_ble_edit_str" $'\n'; local nline=$((ret+1)) + ((count<nline)) && break + ((count-=nline)) + done + if ((count)); then + if ((offset<0)); then + ble-edit/content/find-logical-eol 0 $((nline-count-1)) + ble/keymap:vi/needs-eol-fix "$ret" && ((ret--)) + else + ble-edit/content/find-logical-bol 0 "$count" + fi + _ble_edit_ind=$ret + fi + return 0 +} +function ble/keymap:vi/get-index-of-relative-line { + local ind=${1:-$_ble_edit_ind} offset=$2 + if ((offset==0)); then + index=$ind + return 0 + fi + local count=$((offset<0?-offset:offset)) + local ret + ble-edit/content/find-logical-bol "$ind" 0; local bol1=$ret + ble-edit/content/find-logical-bol "$ind" "$offset"; local bol2=$ret + if ble/edit/use-textmap; then + local b1x b1y; ble/textmap#getxy.cur --prefix=b1 "$bol1" + local b2x b2y; ble/textmap#getxy.cur --prefix=b2 "$bol2" + ble-edit/content/find-logical-eol "$bol2"; local eol2=$ret + local c1x c1y; ble/textmap#getxy.cur --prefix=c1 "$ind" + local e2x e2y; ble/textmap#getxy.cur --prefix=e2 "$eol2" + local x=$c1x y=$((b2y+c1y-b1y)) + ((y>e2y&&(x=e2x,y=e2y))) + ble/textmap#get-index-at "$x" "$y" # local variable "index" is set here + else + ble-edit/content/find-logical-eol "$bol2"; local eol2=$ret + ((index=bol2+ind-bol1,index>eol2&&(index=eol2))) + fi +} +function ble/widget/vi-command/relative-line.impl { + local offset=$1 flag=$2 reg=$3 opts=$4 + ((offset==0)) && return 0 + if [[ $flag ]]; then + ble/widget/vi-command/linewise-goto.impl "$_ble_edit_ind:$offset" "$flag" "$reg" preserve_column:require_multiline + return "$?" + fi + local count=$((offset<0?-offset:offset)) ret + if ((offset<0)); then + ble/string#count-char "${_ble_edit_str::_ble_edit_ind}" $'\n' + else + ble/string#count-char "${_ble_edit_str:_ble_edit_ind}" $'\n' + fi + ((count-=count<ret?count:ret)) + if ((count==0)); then + local index; ble/keymap:vi/get-index-of-relative-line "$_ble_edit_ind" "$offset" + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + _ble_edit_ind=$index + ble/keymap:vi/adjust-command-mode + return 0 + fi + if [[ $_ble_decode_keymap == vi_nmap && :$opts: == *:history:* ]]; then + if ble/widget/vi-command/.history-relative-line $((offset>=0?count:-count)) || ((nmove)); then + ble/keymap:vi/adjust-command-mode + return 0 + fi + fi + ble/widget/vi-command/bell + return 1 +} +function ble/widget/vi-command/forward-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/relative-line.impl "$ARG" "$FLAG" "$REG" history +} +function ble/widget/vi-command/backward-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/relative-line.impl $((-ARG)) "$FLAG" "$REG" history +} +function ble/widget/vi-command/graphical-relative-line.impl { + local offset=$1 flag=$2 reg=$3 opts=$4 + local index move + if ble/edit/use-textmap; then + local x y ax ay + ble/textmap#getxy.cur "$_ble_edit_ind" + ((ax=x,ay=y+offset, + ay<_ble_textmap_begy?(ay=_ble_textmap_begy): + (ay>_ble_textmap_endy?(ay=_ble_textmap_endy):0))) + ble/textmap#get-index-at "$ax" "$ay" + ble/textmap#getxy.cur --prefix=a "$index" + ((offset-=move=ay-y)) + else + local ret ind=$_ble_edit_ind + ble-edit/content/find-logical-bol "$ind" 0; local bol1=$ret + ble-edit/content/find-logical-bol "$ind" "$offset"; local bol2=$ret + ble-edit/content/find-logical-eol "$bol2"; local eol2=$ret + ((index=bol2+ind-bol1,index>eol2&&(index=eol2))) + if ((index>ind)); then + ble/string#count-char "${_ble_edit_str:ind:index-ind}" $'\n' + ((offset+=move=-ret)) + elif ((index<ind)); then + ble/string#count-char "${_ble_edit_str:index:ind-index}" $'\n' + ((offset+=move=ret)) + fi + fi + if ((offset==0)); then + ble/widget/vi-command/exclusive-goto.impl "$index" "$flag" "$reg" + return "$?" + fi + if [[ ! $flag && $_ble_decode_keymap == vi_nmap && :$opts: == *:history:* ]]; then + if ble/widget/vi-command/.history-relative-line "$offset"; then + ble/keymap:vi/adjust-command-mode + return 0 + fi + fi + ((move)) && ble/widget/vi-command/exclusive-goto.impl "$index" + ble/widget/vi-command/bell + return 1 +} +function ble/widget/vi-command/graphical-forward-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/graphical-relative-line.impl "$ARG" "$FLAG" "$REG" +} +function ble/widget/vi-command/graphical-backward-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/graphical-relative-line.impl $((-ARG)) "$FLAG" "$REG" +} +function ble/widget/vi-command/relative-first-non-space.impl { + local arg=$1 flag=$2 reg=$3 opts=$4 + local ret ind=$_ble_edit_ind + ble-edit/content/find-logical-bol "$ind" "$arg"; local bolx=$ret + ble-edit/content/find-non-space "$bolx"; local nolx=$ret + ((_ble_keymap_vi_single_command==2&&_ble_keymap_vi_single_command--)) + if [[ $flag ]]; then + if [[ :$opts: == *:charwise:* ]]; then + ble-edit/content/nonbol-eolp "$nolx" && ((nolx--)) + ble/widget/vi-command/exclusive-goto.impl "$nolx" "$flag" "$reg" nobell + elif [[ :$opts: == *:multiline:* ]]; then + ble/widget/vi-command/linewise-goto.impl "$nolx" "$flag" "$reg" require_multiline:bolx="$bolx":nolx="$nolx" + else + ble/widget/vi-command/linewise-goto.impl "$nolx" "$flag" "$reg" bolx="$bolx":nolx="$nolx" + fi + return "$?" + fi + local count=$((arg<0?-arg:arg)) nmove=0 + if ((count)); then + local beg end; ((nolx<ind?(beg=nolx,end=ind):(beg=ind,end=nolx))) + ble/string#count-char "${_ble_edit_str:beg:end-beg}" $'\n'; nmove=$ret + ((count-=nmove)) + fi + if ((count==0)); then + ble/keymap:vi/needs-eol-fix "$nolx" && ((nolx--)) + _ble_edit_ind=$nolx + ble/keymap:vi/adjust-command-mode + return 0 + fi + if [[ $_ble_decode_keymap == vi_nmap && :$opts: == *:history:* ]] && ble/widget/vi-command/.history-relative-line $((arg>=0?count:-count)); then + ble/widget/vi-command/first-non-space + elif ((nmove)); then + ble/keymap:vi/needs-eol-fix "$nolx" && ((nolx--)) + _ble_edit_ind=$nolx + ble/keymap:vi/adjust-command-mode + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi-command/first-non-space { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/relative-first-non-space.impl 0 "$FLAG" "$REG" charwise:history +} +function ble/widget/vi-command/forward-first-non-space { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/relative-first-non-space.impl "$ARG" "$FLAG" "$REG" multiline:history +} +function ble/widget/vi-command/backward-first-non-space { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/relative-first-non-space.impl $((-ARG)) "$FLAG" "$REG" multiline:history +} +function ble/widget/vi-command/first-non-space-forward { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/relative-first-non-space.impl $((ARG-1)) "$FLAG" "$REG" history +} +function ble/widget/vi-command/forward-eol { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + if ((ARG>1)) && [[ ${_ble_edit_str:_ble_edit_ind} != *$'\n'* ]]; then + ble/widget/vi-command/bell + return 1 + fi + local ret index + ble-edit/content/find-logical-eol "$_ble_edit_ind" $((ARG-1)); index=$ret + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + ble/widget/vi-command/inclusive-goto.impl "$index" "$FLAG" "$REG" nobell + [[ $_ble_decode_keymap == vi_[xs]map ]] && + ble/keymap:vi/xmap/add-eol-extension # 末尾拡張 +} +function ble/widget/vi-command/beginning-of-graphical-line { + if ble/edit/use-textmap; then + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local x y index + ble/textmap#getxy.cur "$_ble_edit_ind" + ble/textmap#get-index-at 0 "$y" + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" nobell + else + ble/widget/vi-command/beginning-of-line + fi +} +function ble/widget/vi-command/graphical-first-non-space { + if ble/edit/use-textmap; then + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local x y index ret + ble/textmap#getxy.cur "$_ble_edit_ind" + ble/textmap#get-index-at 0 "$y" + ble-edit/content/find-non-space "$index" + ble/keymap:vi/needs-eol-fix "$ret" && ((ret--)) + ble/widget/vi-command/exclusive-goto.impl "$ret" "$FLAG" "$REG" nobell + else + ble/widget/vi-command/first-non-space + fi +} +function ble/widget/vi-command/graphical-forward-eol { + if ble/edit/use-textmap; then + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local x y index + ble/textmap#getxy.cur "$_ble_edit_ind" + ble/textmap#get-index-at $((_ble_textmap_cols-1)) $((y+ARG-1)) + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + ble/widget/vi-command/inclusive-goto.impl "$index" "$FLAG" "$REG" nobell + else + ble/widget/vi-command/forward-eol + fi +} +function ble/widget/vi-command/middle-of-graphical-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local index + if ble/edit/use-textmap; then + local x y + ble/textmap#getxy.cur "$_ble_edit_ind" + ble/textmap#get-index-at $((_ble_textmap_cols/2)) "$y" + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + else + local ret + ble-edit/content/find-logical-bol; local bol=$ret + ble-edit/content/find-logical-eol; local eol=$ret + ((index=(bol+${COLUMNS:-eol})/2, + index>eol&&(index=eol), + bol<eol&&index==eol&&(index--))) + fi + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" nobell +} +function ble/widget/vi-command/last-non-space { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + ble-edit/content/find-logical-eol "$_ble_edit_ind" $((ARG-1)); local index=$ret + if ((ARG>1)) && [[ ${_ble_edit_str:_ble_edit_ind:index-_ble_edit_ind} != *$'\n'* ]]; then + ble/widget/vi-command/bell + return 1 + fi + local rex=$'([^ \t\n]?[ \t]+|[^ \t\n])$' + [[ ${_ble_edit_str::index} =~ $rex ]] && ((index-=${#BASH_REMATCH})) + ble/widget/vi-command/inclusive-goto.impl "$index" "$FLAG" "$REG" nobell +} +_ble_keymap_vi_previous_scroll= +function ble/widget/vi_nmap/scroll.impl { + local opts=$1 + local height=${_ble_canvas_panel_height[_ble_textarea_panel]} + local ARG FLAG REG; ble/keymap:vi/get-arg "$_ble_keymap_vi_previous_scroll" + _ble_keymap_vi_previous_scroll=$ARG + [[ $ARG ]] || ((ARG=height/2)) + [[ :$opts: == *:backward:* ]] && ((ARG=-ARG)) + ble/widget/.update-textmap + if [[ :$opts: == *:cursor:* ]]; then + local x y index ret + ble/textmap#getxy.cur "$_ble_edit_ind" + ble/textmap#get-index-at 0 $((y+ARG)) + ble-edit/content/find-non-space "$index" + ble/keymap:vi/needs-eol-fix "$ret" && ((ret--)) + _ble_edit_ind=$ret + ble/keymap:vi/adjust-command-mode + ((_ble_textmap_endy<height)) && return 0 + local ax ay + ble/textmap#getxy.cur --prefix=a "$_ble_edit_ind" + local max_scroll=$((_ble_textmap_endy+1-height)) + ((_ble_textarea_scroll_new+=ay-y)) + if ((_ble_textarea_scroll_new<0)); then + _ble_textarea_scroll_new=0 + elif ((_ble_textarea_scroll_new>max_scroll)); then + _ble_textarea_scroll_new=$max_scroll + fi + else + ((_ble_textmap_endy<height)) && return 0 + local max_scroll=$((_ble_textmap_endy+1-height)) + ((_ble_textarea_scroll_new+=ARG)) + if ((_ble_textarea_scroll_new<0)); then + _ble_textarea_scroll_new=0 + elif ((_ble_textarea_scroll_new>max_scroll)); then + _ble_textarea_scroll_new=$max_scroll + fi + local ay=$((_ble_textarea_scroll_new+_ble_textmap_begy)) + local by=$((_ble_textarea_scroll_new+height-1)) + ((_ble_textarea_scroll_new&&ay++)) + ((_ble_textarea_scroll_new!=0&&ay<by&&ay++, + _ble_textarea_scroll_new!=max_scroll&&ay<by&&by--)) + local x y + ble/textmap#getxy.cur "$_ble_edit_ind" + if ((y<ay?(y=ay,1):(y>by?(y=by,1):0))); then + local index + ble/textmap#get-index-at "$x" "$y" + _ble_edit_ind=$index + fi + ble/keymap:vi/adjust-command-mode + fi +} +function ble/widget/vi_nmap/forward-line-scroll { + ble/widget/vi_nmap/scroll.impl forward:cursor +} +function ble/widget/vi_nmap/backward-line-scroll { + ble/widget/vi_nmap/scroll.impl backward:cursor +} +function ble/widget/vi_nmap/forward-scroll { + ble/widget/vi_nmap/scroll.impl forward +} +function ble/widget/vi_nmap/backward-scroll { + ble/widget/vi_nmap/scroll.impl backward +} +function ble/widget/vi_nmap/pagedown { + local height=${_ble_canvas_panel_height[_ble_textarea_panel]} + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/.update-textmap + local x y + ble/textmap#getxy.cur "$_ble_edit_ind" + if ((y==_ble_textmap_endy)); then + ble/widget/vi-command/bell + return 1 + fi + local vheight=$((height-_ble_textmap_begy-1)) + local ybase=$((_ble_textarea_scroll_new+height-1)) + local y1=$((ybase+(ARG-1)*(vheight-2))) + local index ret + ble/textmap#get-index-at 0 "$y1" + ble-edit/content/bolp "$index" && + ble-edit/content/find-non-space "$index"; index=$ret + _ble_edit_ind=$index + local max_scroll=$((_ble_textmap_endy+1-height)) + ble/textmap#getxy.cur "$_ble_edit_ind" + local scroll=$((y<=_ble_textmap_begy+1?0:(y-_ble_textmap_begy-1))) + ((scroll>max_scroll&&(scroll=max_scroll))) + _ble_textarea_scroll_new=$scroll + ble/keymap:vi/adjust-command-mode +} +function ble/widget/vi_nmap/pageup { + local height=${_ble_canvas_panel_height[_ble_textarea_panel]} + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/.update-textmap + if ((!_ble_textarea_scroll_new)); then + ble/widget/vi-command/bell + return 1 + fi + local vheight=$((height-_ble_textmap_begy-1)) + local ybase=$((_ble_textarea_scroll_new+_ble_textmap_begy+1)) + local y1=$((ybase-(ARG-1)*(vheight-2))) + ((y1<_ble_textmap_begy&&(y1=_ble_textmap_begy))) + local index ret + ble/textmap#get-index-at 0 "$y1" + ble-edit/content/bolp "$index" && + ble-edit/content/find-non-space "$index"; index=$ret + _ble_edit_ind=$index + local x y + ble/textmap#getxy.cur "$_ble_edit_ind" + local scroll=$((y-height+2)) + ((scroll<0&&(scroll=0))) + _ble_textarea_scroll_new=$scroll + ble/keymap:vi/adjust-command-mode +} +function ble/widget/vi_nmap/scroll-to-center.impl { + local opts=$1 + ble/widget/.update-textmap + local height=${_ble_canvas_panel_height[_ble_textarea_panel]} + local ARG FLAG REG; ble/keymap:vi/get-arg '' + if [[ ! $ARG && :$opts: == *:pagedown:* ]]; then + local y1=$((_ble_textarea_scroll_new+height)) + local index + ble/textmap#get-index-at 0 "$y1" + ((_ble_edit_ind=index)) + fi + local ret + ble-edit/content/find-logical-bol "$_ble_edit_ind"; local bol1=$ret + if [[ $ARG || :$opts: == *:nol:* ]]; then + if [[ $ARG ]]; then + ble-edit/content/find-logical-bol 0 $((ARG-1)); local bol2=$ret + else + local bol2=$bol1 + fi + if [[ :$opts: == *:nol:* ]]; then + ble-edit/content/find-non-space "$bol2" + _ble_edit_ind=$ret + elif ((bol1!=bol2)); then + local b1x b1y p1x p1y dx dy + ble/textmap#getxy.cur --prefix=b1 "$bol1" + ble/textmap#getxy.cur --prefix=p1 "$_ble_edit_ind" + ((dx=p1x,dy=p1y-b1y)) + local b2x b2y p2x p2y index + ble/textmap#getxy.cur --prefix=b2 "$bol2" + ((p2x=b2x,p2y=b2y+dy)) + ble/textmap#get-index-at "$p2x" "$p2y" + if ble-edit/content/find-logical-bol "$index"; ((ret==bol2)); then + _ble_edit_ind=$index + else + ble-edit/content/find-logical-eol "$bol2" + _ble_edit_ind=$ret + fi + fi + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + fi + if ((_ble_textmap_endy+1>height)); then + local max_scroll=$((_ble_textmap_endy+1-height)) + local b1x b1y + ble/textmap#getxy.cur --prefix=b1 "$bol1" + local scroll= + if [[ :$opts: == *:top:* ]]; then + ((scroll=b1y-(_ble_textmap_begy+2))) + elif [[ :$opts: == *:bottom:* ]]; then + ((scroll=b1y-(height-2))) + else + local vheight=$((height-_ble_textmap_begy-1)) + ((scroll=b1y-(_ble_textmap_begy+1+vheight/2))) + fi + if ((scroll<0)); then + scroll=0 + elif ((scroll>max_scroll)); then + scroll=$max_scroll + fi + _ble_textarea_scroll_new=$scroll + fi + ble/keymap:vi/adjust-command-mode +} +function ble/widget/vi_nmap/scroll-to-center-and-redraw { + ble/widget/vi_nmap/scroll-to-center.impl + ble/widget/redraw-line +} +function ble/widget/vi_nmap/scroll-to-top-and-redraw { + ble/widget/vi_nmap/scroll-to-center.impl top + ble/widget/redraw-line +} +function ble/widget/vi_nmap/scroll-to-bottom-and-redraw { + ble/widget/vi_nmap/scroll-to-center.impl bottom + ble/widget/redraw-line +} +function ble/widget/vi_nmap/scroll-to-center-non-space-and-redraw { + ble/widget/vi_nmap/scroll-to-center.impl nol + ble/widget/redraw-line +} +function ble/widget/vi_nmap/scroll-to-top-non-space-and-redraw { + ble/widget/vi_nmap/scroll-to-center.impl top:nol + ble/widget/redraw-line +} +function ble/widget/vi_nmap/scroll-to-bottom-non-space-and-redraw { + ble/widget/vi_nmap/scroll-to-center.impl bottom:nol + ble/widget/redraw-line +} +function ble/widget/vi_nmap/scroll-or-pagedown-and-redraw { + ble/widget/vi_nmap/scroll-to-center.impl top:nol:pagedown + ble/widget/redraw-line +} +function ble/widget/vi_nmap/paste.impl/block { + local arg=${1:-1} type=$2 + local graphical= + if [[ $type ]]; then + [[ $type == graphical ]] && graphical=1 + else + ble/edit/use-textmap && graphical=1 + fi + local ret cols=$_ble_textmap_cols + local -a afill; ble/string#split-words afill "${_ble_edit_kill_type:2}" + local atext; ble/string#split-lines atext "$_ble_edit_kill_ring" + local ntext=${#atext[@]} + if [[ $graphical ]]; then + ble-edit/content/find-logical-bol; local bol=$ret + local bx by x y c + ble/textmap#getxy.cur --prefix=b "$bol" + ble/textmap#getxy.cur "$_ble_edit_ind" + ((y-=by,c=y*cols+x)) + else + ble-edit/content/find-logical-bol; local bol=$ret + local c=$((_ble_edit_ind-bol)) + fi + local -a ins_beg=() ins_end=() ins_text=() + local i is_newline= + for ((i=0;i<ntext;i++)); do + if ((i>0)); then + ble-edit/content/find-logical-bol "$bol" 1 + if ((bol==ret)); then + is_newline=1 + else + bol=$ret + [[ $graphical ]] && ble/textmap#getxy.cur --prefix=b "$bol" + fi + fi + local text=${atext[i]} + local fill=$((afill[i])) + if ((arg>1)); then + ret= + ((fill)) && ble/string#repeat ' ' "$fill" + ble/string#repeat "$text$ret" "$arg" + text=${ret::${#ret}-fill} + fi + local index iend= + if [[ $is_newline ]]; then + index=${#_ble_edit_str} + ble/string#repeat ' ' "$c" + text=$'\n'$ret$text + elif [[ $graphical ]]; then + ble-edit/content/find-logical-eol "$bol"; local eol=$ret + ble/textmap#get-index-at "$x" $((by+y)); ((index>eol&&(index=eol))) + local ax ay ac; ble/textmap#getxy.out --prefix=a "$index" + ((ay-=by,ac=ay*cols+ax)) + if ((ac<c)); then + ble/string#repeat ' ' $((c-ac)) + text=$ret$text + if ((index<eol)) && [[ ${_ble_edit_str:index:1} == $'\t' ]]; then + local rx ry rc; ble/textmap#getxy.out --prefix=r $((index+1)) + ((rc=(ry-by)*cols+rx)) + ble/string#repeat ' ' $((rc-c)) + text=$text$ret + iend=$((index+1)) + fi + fi + if ((index<eol&&fill)); then + ble/string#repeat ' ' "$fill" + text=$text$ret + fi + else + ble-edit/content/find-logical-eol "$bol"; local eol=$ret + local index=$((bol+c)) + if ((index<eol)); then + if ((fill)); then + ble/string#repeat ' ' "$fill" + text=$text$ret + fi + elif ((index>eol)); then + ble/string#repeat ' ' $((index-eol)) + text=$ret$text + index=$eol + fi + fi + ble/array#push ins_beg "$index" + ble/array#push ins_end "${iend:-$index}" + ble/array#push ins_text "$text" + done + ble/keymap:vi/mark/start-edit-area + local i=${#ins_beg[@]} + while ((i--)); do + local ibeg=${ins_beg[i]} iend=${ins_end[i]} text=${ins_text[i]} + ble/widget/.replace-range "$ibeg" "$iend" "$text" + done + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/repeat/record + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + ble/keymap:vi/adjust-command-mode +} +function ble/widget/vi_nmap/paste.impl { + local arg=$1 reg=$2 is_after=$3 + if [[ $reg ]]; then + local _ble_edit_kill_ring _ble_edit_kill_type + ble/keymap:vi/register#load "$reg" + fi + [[ $_ble_edit_kill_ring ]] || return 0 + local ret + if [[ $_ble_edit_kill_type == L ]]; then + ble/string#repeat "$_ble_edit_kill_ring" "$arg" + local content=$ret + local index dbeg dend + if ((is_after)); then + ble-edit/content/find-logical-eol; index=$ret + if ((index==${#_ble_edit_str})); then + content=$'\n'${content%$'\n'} + ((dbeg=index+1,dend=index+${#content})) + else + ((index++,dbeg=index,dend=index+${#content}-1)) + fi + else + ble-edit/content/find-logical-bol + ((index=ret,dbeg=index,dend=index+${#content}-1)) + fi + ble/widget/.replace-range "$index" "$index" "$content" + _ble_edit_ind=$dbeg + ble/keymap:vi/mark/set-previous-edit-area "$dbeg" "$dend" + ble/keymap:vi/repeat/record + ble/widget/vi-command/first-non-space + elif [[ $_ble_edit_kill_type == B:* ]]; then + if ((is_after)) && ! ble-edit/content/eolp; then + ((_ble_edit_ind++)) + fi + ble/widget/vi_nmap/paste.impl/block "$arg" + else + if ((is_after)) && ! ble-edit/content/eolp; then + ((_ble_edit_ind++)) + fi + ble/string#repeat "$_ble_edit_kill_ring" "$arg" + local beg=$_ble_edit_ind + ble/widget/.insert-string "$ret" + local end=$_ble_edit_ind + ble/keymap:vi/mark/set-previous-edit-area "$beg" "$end" + ble/keymap:vi/repeat/record + [[ $_ble_keymap_vi_single_command ]] || ((_ble_edit_ind--)) + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + ble/keymap:vi/adjust-command-mode + fi + return 0 +} +function ble/widget/vi_nmap/paste-after { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi_nmap/paste.impl "$ARG" "$REG" 1 +} +function ble/widget/vi_nmap/paste-before { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi_nmap/paste.impl "$ARG" "$REG" 0 +} +function ble/widget/vi_nmap/kill-forward-char { + _ble_keymap_vi_opfunc=d + ble/widget/vi-command/forward-char +} +function ble/widget/vi_nmap/kill-forward-char-and-insert { + _ble_keymap_vi_opfunc=c + ble/widget/vi-command/forward-char +} +function ble/widget/vi_nmap/kill-backward-char { + _ble_keymap_vi_opfunc=d + ble/widget/vi-command/backward-char +} +function ble/widget/vi_nmap/kill-forward-line { + _ble_keymap_vi_opfunc=d + ble/widget/vi-command/forward-eol +} +function ble/widget/vi_nmap/kill-forward-line-and-insert { + _ble_keymap_vi_opfunc=c + ble/widget/vi-command/forward-eol +} +function ble/widget/vi-command/forward-word.impl { + local arg=$1 flag=$2 reg=$3 rex_word=$4 + local ifs=$_ble_term_IFS + if [[ $flag == c && ${_ble_edit_str:_ble_edit_ind:1} != [$ifs] ]]; then + ble/widget/vi-command/forward-word-end.impl "$arg" "$flag" "$reg" "$rex_word" allow_here + return "$?" + fi + local b=$'[ \t]' n=$'\n' + local rex="^((($rex_word)$n?|$b+$n?|$n)($b+$n)*$b*){0,$arg}" # 単語先頭または空行に止まる + [[ ${_ble_edit_str:_ble_edit_ind} =~ $rex ]] + local index=$((_ble_edit_ind+${#BASH_REMATCH})) + if [[ $flag ]]; then + local rematch1=${BASH_REMATCH[1]} + if local rex="$n$b*\$"; [[ $rematch1 =~ $rex ]]; then + local suffix_len=${#BASH_REMATCH} + ((suffix_len<${#rematch1})) && + ((index-=suffix_len)) + fi + fi + ble/widget/vi-command/exclusive-goto.impl "$index" "$flag" "$reg" +} +function ble/widget/vi-command/forward-word-end.impl { + local arg=$1 flag=$2 reg=$3 rex_word=$4 opts=$5 + local IFS=$_ble_term_IFS + local rex="^([$IFS]*($rex_word)?){0,$arg}" # 単語末端に止まる。空行には止まらない + local offset=1; [[ :$opts: == *:allow_here:* ]] && offset=0 + [[ ${_ble_edit_str:_ble_edit_ind+offset} =~ $rex ]] + local index=$((_ble_edit_ind+offset+${#BASH_REMATCH}-1)) + ((index<_ble_edit_ind&&(index=_ble_edit_ind))) + [[ ! $flag && $BASH_REMATCH && ${_ble_edit_str:index:1} == [$IFS] ]] && ble/widget/.bell + ble/widget/vi-command/inclusive-goto.impl "$index" "$flag" "$reg" +} +function ble/widget/vi-command/backward-word.impl { + local arg=$1 flag=$2 reg=$3 rex_word=$4 + local b=$'[ \t]' n=$'\n' + local rex="((($rex_word)$n?|$b+$n?|$n)($b+$n)*$b*){0,$arg}\$" # 単語先頭または空行に止まる + [[ ${_ble_edit_str::_ble_edit_ind} =~ $rex ]] + local index=$((_ble_edit_ind-${#BASH_REMATCH})) + ble/widget/vi-command/exclusive-goto.impl "$index" "$flag" "$reg" +} +function ble/widget/vi-command/backward-word-end.impl { + local arg=$1 flag=$2 reg=$3 rex_word=$4 + local i=$'[ \t\n]' b=$'[ \t]' n=$'\n' w="($rex_word)" + local rex1="(^|$w$n?|$n)($b+$n)*$b*" + local rex="($rex1)($rex1){$((arg-1))}($rex_word|$i)\$" # 単語末端または空行に止まる + [[ ${_ble_edit_str::_ble_edit_ind+1} =~ $rex ]] + local index=$((_ble_edit_ind+1-${#BASH_REMATCH})) + local rematch3=${BASH_REMATCH[3]} # 最初の ($rex_word) + [[ $rematch3 ]] && ((index+=${#rematch3}-1)) + ble/widget/vi-command/inclusive-goto.impl "$index" "$flag" "$reg" +} +function ble/widget/vi-command/forward-vword { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/forward-word.impl "$ARG" "$FLAG" "$REG" "$_ble_keymap_vi_REX_WORD" +} +function ble/widget/vi-command/forward-vword-end { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/forward-word-end.impl "$ARG" "$FLAG" "$REG" "$_ble_keymap_vi_REX_WORD" +} +function ble/widget/vi-command/backward-vword { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/backward-word.impl "$ARG" "$FLAG" "$REG" "$_ble_keymap_vi_REX_WORD" +} +function ble/widget/vi-command/backward-vword-end { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/backward-word-end.impl "$ARG" "$FLAG" "$REG" "$_ble_keymap_vi_REX_WORD" +} +function ble/widget/vi-command/forward-uword { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/forward-word.impl "$ARG" "$FLAG" "$REG" $'[^ \t\n]+' +} +function ble/widget/vi-command/forward-uword-end { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/forward-word-end.impl "$ARG" "$FLAG" "$REG" $'[^ \t\n]+' +} +function ble/widget/vi-command/backward-uword { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/backward-word.impl "$ARG" "$FLAG" "$REG" $'[^ \t\n]+' +} +function ble/widget/vi-command/backward-uword-end { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/backward-word-end.impl "$ARG" "$FLAG" "$REG" $'[^ \t\n]+' +} +function ble/widget/vi-command/nth-column { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret index + ble-edit/content/find-logical-bol; local bol=$ret + ble-edit/content/find-logical-eol; local eol=$ret + if ble/edit/use-textmap; then + local bx by; ble/textmap#getxy.cur --prefix=b "$bol" # Note: 先頭行はプロンプトにより bx!=0 + local ex ey; ble/textmap#getxy.cur --prefix=e "$eol" + local dstx=$((bx+ARG-1)) dsty=$by cols=${COLUMNS:-80} + ((dsty+=dstx/cols,dstx%=cols)) + ((dsty>ey&&(dsty=ey,dstx=ex))) + ble/textmap#get-index-at "$dstx" "$dsty" # local variable "index" is set here + [[ $_ble_decode_keymap != vi_[xs]map ]] && + ble-edit/content/nonbol-eolp "$index" && ((index--)) + else + [[ $_ble_decode_keymap != vi_[xs]map ]] && + ble-edit/content/nonbol-eolp "$eol" && ((eol--)) + ((index=bol+ARG-1,index>eol&&(index=eol))) + fi + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" nobell +} +function ble/widget/vi-command/nth-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + [[ $FLAG ]] || ble/keymap:vi/mark/set-jump # `` + ble/widget/vi-command/linewise-goto.impl 0:$((ARG-1)) "$FLAG" "$REG" +} +function ble/widget/vi-command/nth-last-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + [[ $FLAG ]] || ble/keymap:vi/mark/set-jump # `` + ble/widget/vi-command/linewise-goto.impl ${#_ble_edit_str}:$((-(ARG-1))) "$FLAG" "$REG" +} +function ble/widget/vi-command/history-beginning { + local ARG FLAG REG; ble/keymap:vi/get-arg 0 + if [[ $FLAG ]]; then + if ((ARG)); then + _ble_keymap_vi_oparg=$ARG + else + _ble_keymap_vi_oparg= + fi + _ble_keymap_vi_opfunc=$FLAG + _ble_keymap_vi_reg=$REG + ble/widget/vi-command/nth-line + return "$?" + fi + if ((ARG)); then + ble-edit/history/goto $((ARG-1)) + else + ble/widget/history-beginning + fi + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-command/history-end { + local ARG FLAG REG; ble/keymap:vi/get-arg 0 + if [[ $FLAG ]]; then + _ble_keymap_vi_opfunc=$FLAG + _ble_keymap_vi_reg=$REG + if ((ARG)); then + _ble_keymap_vi_oparg=$ARG + ble/widget/vi-command/nth-line + else + _ble_keymap_vi_oparg= + ble/widget/vi-command/nth-last-line + fi + return "$?" + fi + if ((ARG)); then + ble-edit/history/goto $((ARG-1)) + else + ble/widget/history-end + fi + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-command/last-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 0 + [[ $FLAG ]] || ble/keymap:vi/mark/set-jump # `` + if ((ARG)); then + ble/widget/vi-command/linewise-goto.impl 0:$((ARG-1)) "$FLAG" "$REG" + else + ble/widget/vi-command/linewise-goto.impl ${#_ble_edit_str}:0 "$FLAG" "$REG" + fi +} +function ble/widget/vi-command/first-nol { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi-command/linewise-goto.impl 0:$((ARG-1)) "$FLAG" "$REG" +} +function ble/widget/vi-command/last-eol { + local ARG FLAG REG; ble/keymap:vi/get-arg '' + local ret index + if [[ $ARG ]]; then + ble-edit/content/find-logical-eol 0 $((ARG-1)); index=$ret + else + ble-edit/content/find-logical-eol ${#_ble_edit_str}; index=$ret + fi + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + ble/widget/vi-command/inclusive-goto.impl "$index" "$FLAG" "$REG" nobell +} +function ble/widget/vi_nmap/replace-char.impl { + local key=$1 overwrite_mode=${2:-R} + _ble_edit_overwrite_mode= + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + if ((key==(_ble_decode_Ctrl|91))); then # C-[ + ble/keymap:vi/adjust-command-mode + return 27 + elif ! ble/keymap:vi/k2c "$key"; then + ble/widget/vi-command/bell + return 1 + fi + local pos=$_ble_edit_ind + ble/keymap:vi/mark/start-edit-area + { + local -a KEYS; KEYS=("$ret") + local _ble_edit_arg=$ARG + local _ble_edit_overwrite_mode=$overwrite_mode + local ble_widget_self_insert_opts=nolineext + ble/widget/self-insert + ble/util/unlocal KEYS + } + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/repeat/record + ((pos<_ble_edit_ind&&_ble_edit_ind--)) + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi_nmap/replace-char.hook { + ble/widget/vi_nmap/replace-char.impl "$1" R +} +function ble/widget/vi_nmap/replace-char { + _ble_edit_overwrite_mode=R + ble/keymap:vi/async-read-char ble/widget/vi_nmap/replace-char.hook +} +function ble/widget/vi_nmap/virtual-replace-char.hook { + ble/widget/vi_nmap/replace-char.impl "$1" 1 +} +function ble/widget/vi_nmap/virtual-replace-char { + _ble_edit_overwrite_mode=1 + ble/keymap:vi/async-read-char ble/widget/vi_nmap/virtual-replace-char.hook +} +function ble/widget/vi_nmap/connect-line-with-space { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + ble-edit/content/find-logical-eol; local eol1=$ret + ble-edit/content/find-logical-eol "$_ble_edit_ind" $((ARG<=1?1:ARG-1)); local eol2=$ret + ble-edit/content/find-logical-bol "$eol2"; local bol2=$ret + if ((eol1<eol2)); then + local text=${_ble_edit_str:eol1:eol2-eol1} + text=${text//$'\n'/' '} + ble/widget/.replace-range "$eol1" "$eol2" "$text" + ble/keymap:vi/mark/set-previous-edit-area "$eol1" "$eol2" + ble/keymap:vi/repeat/record + _ble_edit_ind=$((bol2-1)) + ble/keymap:vi/adjust-command-mode + return 0 + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi_nmap/connect-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + ble-edit/content/find-logical-eol; local eol1=$ret + ble-edit/content/find-logical-eol "$_ble_edit_ind" $((ARG<=1?1:ARG-1)); local eol2=$ret + ble-edit/content/find-logical-bol "$eol2"; local bol2=$ret + if ((eol1<eol2)); then + local text=${_ble_edit_str:eol1:bol2-eol1} + text=${text//$'\n'} + ble/widget/.replace-range "$eol1" "$bol2" "$text" + local delta=$((${#text}-(bol2-eol1))) + ble/keymap:vi/mark/set-previous-edit-area "$eol1" $((eol2+delta)) + ble/keymap:vi/repeat/record + _ble_edit_ind=$((bol2+delta)) + ble/keymap:vi/adjust-command-mode + return 0 + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi_nmap/insert-mode-at-forward-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + ble-edit/content/find-logical-bol; local bol=$ret + ble-edit/content/find-logical-eol; local eol=$ret + ble-edit/content/find-non-space "$bol"; local indent=${_ble_edit_str:bol:ret-bol} + _ble_edit_ind=$eol + ble/widget/.insert-string $'\n'"$indent" + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_nmap/insert-mode-at-backward-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + ble-edit/content/find-logical-bol; local bol=$ret + ble-edit/content/find-non-space "$bol"; local indent=${_ble_edit_str:bol:ret-bol} + _ble_edit_ind=$bol + ble/widget/.insert-string "$indent"$'\n' + _ble_edit_ind=$((bol+${#indent})) + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 +} +_ble_keymap_vi_char_search= +function ble/widget/vi-command/search-char.impl/core { + local opts=$1 key=$2 + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret c + [[ $opts != *p* ]]; local isprev=$? + [[ $opts != *r* ]]; local isrepeat=$? + if ((isrepeat)); then + c=$key + elif ((key==(_ble_decode_Ctrl|91))); then # C-[ -> cancel + return 27 + else + ble/keymap:vi/k2c "$key" || return 1 + ble/util/c2s "$ret"; local c=$ret + fi + [[ $c ]] || return 1 + ((isrepeat)) || _ble_keymap_vi_char_search=$c$opts + local index + if [[ $opts == *b* ]]; then + ble-edit/content/find-logical-bol; local bol=$ret + local base=$_ble_edit_ind + ((isrepeat&&isprev&&base--,base>bol)) || return 1 + local line=${_ble_edit_str:bol:base-bol} + ble/string#last-index-of "$line" "$c" "$ARG" + ((ret>=0)) || return 1 + ((index=bol+ret,isprev&&index++)) + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" nobell + return "$?" + else + ble-edit/content/find-logical-eol; local eol=$ret + local base=$((_ble_edit_ind+1)) + ((isrepeat&&isprev&&base++,base<eol)) || return 1 + local line=${_ble_edit_str:base:eol-base} + ble/string#index-of "$line" "$c" "$ARG" + ((ret>=0)) || return 1 + ((index=base+ret,isprev&&index--)) + ble/widget/vi-command/inclusive-goto.impl "$index" "$FLAG" "$REG" nobell + return "$?" + fi +} +function ble/widget/vi-command/search-char.impl { + if ble/widget/vi-command/search-char.impl/core "$1" "$2"; then + ble/keymap:vi/adjust-command-mode + return 0 + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi-command/search-forward-char { + ble/keymap:vi/async-read-char ble/widget/vi-command/search-char.impl f +} +function ble/widget/vi-command/search-forward-char-prev { + ble/keymap:vi/async-read-char ble/widget/vi-command/search-char.impl fp +} +function ble/widget/vi-command/search-backward-char { + ble/keymap:vi/async-read-char ble/widget/vi-command/search-char.impl b +} +function ble/widget/vi-command/search-backward-char-prev { + ble/keymap:vi/async-read-char ble/widget/vi-command/search-char.impl bp +} +function ble/widget/vi-command/search-char-repeat { + [[ $_ble_keymap_vi_char_search ]] || ble/widget/.bell + local c=${_ble_keymap_vi_char_search::1} opts=${_ble_keymap_vi_char_search:1} + ble/widget/vi-command/search-char.impl "r$opts" "$c" +} +function ble/widget/vi-command/search-char-reverse-repeat { + [[ $_ble_keymap_vi_char_search ]] || ble/widget/.bell + local c=${_ble_keymap_vi_char_search::1} opts=${_ble_keymap_vi_char_search:1} + if [[ $opts == *b* ]]; then + opts=f${opts//b} + else + opts=b${opts//f} + fi + ble/widget/vi-command/search-char.impl "r$opts" "$c" +} +function ble/widget/vi-command/search-matchpair/.search-forward { + ble/string#index-of-chars "$_ble_edit_str" "$ch1$ch2" $((index+1)) +} +function ble/widget/vi-command/search-matchpair/.search-backward { + ble/string#last-index-of-chars "$_ble_edit_str" "$ch1$ch2" "$index" +} +function ble/widget/vi-command/search-matchpair-or { + local ARG FLAG REG; ble/keymap:vi/get-arg -1 + if ((ARG>=0)); then + _ble_keymap_vi_oparg=$ARG + _ble_keymap_vi_opfunc=$FLAG + _ble_keymap_vi_reg=$REG + ble/widget/"$@" + return "$?" + fi + local open='({[' close=')}]' + local ret + ble-edit/content/find-logical-eol; local eol=$ret + if ! ble/string#index-of-chars "${_ble_edit_str::eol}" '(){}[]' "$_ble_edit_ind"; then + ble/keymap:vi/adjust-command-mode + return 1 + fi + local index1=$ret ch1=${_ble_edit_str:ret:1} + if [[ $ch1 == ["$open"] ]]; then + local i=${open%%"$ch"*}; i=${#i} + local ch2=${close:i:1} + local searcher=ble/widget/vi-command/search-matchpair/.search-forward + else + local i=${close%%"$ch"*}; i=${#i} + local ch2=${open:i:1} + local searcher=ble/widget/vi-command/search-matchpair/.search-backward + fi + local index=$index1 count=1 + while "$searcher"; do + index=$ret + if [[ ${_ble_edit_str:ret:1} == "$ch1" ]]; then + ((++count)) + else + ((--count==0)) && break + fi + done + if ((count)); then + ble/keymap:vi/adjust-command-mode + return 1 + fi + [[ $FLAG ]] || ble/keymap:vi/mark/set-jump # `` + ble/widget/vi-command/inclusive-goto.impl "$index" "$FLAG" "$REG" nobell +} +function ble/widget/vi-command/percentage-line { + local ARG FLAG REG; ble/keymap:vi/get-arg 0 + local ret; ble/string#count-char "$_ble_edit_str" $'\n'; local nline=$((ret+1)) + local iline=$(((ARG*nline+99)/100)) + ble/widget/vi-command/linewise-goto.impl 0:$((iline-1)) "$FLAG" "$REG" +} +function ble/widget/vi-command/nth-byte { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ((ARG--)) + local offset=0 text=$_ble_edit_str len=${#_ble_edit_str} + local left nleft ret + while ((ARG>0&&len>1)); do + left=${text::len/2} + ble/util/strlen "$left"; nleft=$ret + if ((ARG<nleft)); then + text=$left + ((len/=2)) + else + text=${text:len/2} + ((offset+=len/2, + ARG-=nleft, + len-=len/2)) + fi + done + ble/keymap:vi/needs-eol-fix "$offset" && ((offset--)) + ble/widget/vi-command/exclusive-goto.impl "$offset" "$FLAG" "$REG" nobell +} +_ble_keymap_vi_text_object= +function ble/keymap:vi/text-object/word.extend-forward { + local rex + flags= + [[ ${_ble_edit_str:beg:1} == ["$ifs"] ]] && flags=${flags}A + if [[ $_ble_decode_keymap != vi_[xs]map ]]; then + flags=${flags}I + elif ((_ble_edit_mark==_ble_edit_ind)); then + flags=${flags}I + fi + local rex_unit + local W='('$rex_word')' b='['$space']' n=$nl + if [[ $type == i* ]]; then + rex_unit='^'$W'|^'$b'+|^'$n + elif [[ $type == a* ]]; then + rex_unit='^'$W$b'*|^'$b'+'$W'|^'$b'*'$n'('$b'+'$n')*('$n'|'$b'*'$W')' + else + return 1 + fi + local i rematch= + for ((i=0;i<arg;i++)); do + if ((i==0)) && [[ $flags == *I* ]]; then + rex='('$rex_word')$|['$space']*['$ifs']$' + [[ ${_ble_edit_str::beg+1} =~ $rex ]] && + ((beg-=${#BASH_REMATCH}-1,end=beg)) + else + [[ ${_ble_edit_str:end:1} == $'\n' ]] && ((end++)) + fi + [[ ${_ble_edit_str:end} =~ $rex_unit ]] || return 1 + rematch=$BASH_REMATCH + ((end+=${#rematch})) + [[ $type == a* && $rematch == *$'\n\n' ]] && ((end--)) + if ((i==0)) && [[ $flags == *I* ]] || ((i==arg-1)); then + [[ $type == i* && $rematch == *"$nl" ]] && ((end--)) + fi + done + [[ ${_ble_edit_str:end-1:1} == *["$ifs"] ]] && flags=${flags}Z + if [[ $type == a* && $flags != *[AZ]* ]]; then + if rex='['$space']+$'; [[ ${_ble_edit_str::beg} =~ $rex ]]; then + local p=$((beg-${#BASH_REMATCH})) + ble-edit/content/bolp "$p" || beg=$p + fi + fi + return 0 +} +function ble/keymap:vi/text-object/word.extend-backward { + local rex_unit= + local W='('$rex_word')' b='['$space']' n=$nl + if [[ $type == i* ]]; then + rex_unit='('$W'|'$b'+)'$n'?$|'$n'$' + elif [[ $type == a* ]]; then + rex_unit=$b'*'$W$n'?$|'$W'?'$b'*('$n'('$b'+'$n')*'$b'*)?('$b$n'?|'$n')$' + else + return 1 + fi + local count=$arg + while ((count--)); do + [[ ${_ble_edit_str::beg} =~ $rex_unit ]] || return 1 + ((beg-=${#BASH_REMATCH})) + local match=${BASH_REMATCH%"$nl"} + if ((beg==0&&${#match}>=2)); then + if [[ $type == i* ]]; then + [[ $match == ["$space"]* ]] && beg=1 + elif [[ $type == a* ]]; then + [[ $match == *[!"$ifs"] ]] && beg=1 + fi + fi + done + return 0 +} +function ble/keymap:vi/text-object/word.impl { + local arg=$1 flag=$2 reg=$3 type=$4 + local space=$' \t' nl=$'\n' ifs=$_ble_term_IFS + ((arg==0)) && return 0 + local rex_word + if [[ $type == ?W ]]; then + rex_word="[^$ifs]+" + else + rex_word=$_ble_keymap_vi_REX_WORD + fi + local index=$_ble_edit_ind + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + if ((index<_ble_edit_mark)); then + local beg=$index + if ble/keymap:vi/text-object/word.extend-backward; then + _ble_edit_ind=$beg + else + _ble_edit_ind=0 + ble/widget/.bell + fi + ble/keymap:vi/adjust-command-mode + return 0 + fi + fi + local beg=$index end=$index flags= + if ! ble/keymap:vi/text-object/word.extend-forward; then + index=${#_ble_edit_str} + ble-edit/content/nonbol-eolp "$index" && ((index--)) + _ble_edit_ind=$index + ble/widget/vi-command/bell + return 1 + fi + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + ((end--)) + ble-edit/content/nonbol-eolp "$end" && ((end--)) + ((beg<_ble_edit_mark)) && _ble_edit_mark=$beg + [[ $_ble_edit_mark_active == vi_line ]] && + _ble_edit_mark_active=vi_char + _ble_edit_ind=$end + ble/keymap:vi/adjust-command-mode + return 0 + else + ble/widget/vi-command/exclusive-range.impl "$beg" "$end" "$flag" "$reg" + fi +} +function ble/keymap:vi/text-object:quote/.next { + local index=${1:-$((_ble_edit_ind+1))} nl=$'\n' + local rex="^[^$nl$quote]*$quote" + [[ ${_ble_edit_str:index} =~ $rex ]] || return 1 + ((ret=index+${#BASH_REMATCH}-1)) + return 0 +} +function ble/keymap:vi/text-object:quote/.prev { + local index=${1:-_ble_edit_ind} nl=$'\n' + local rex="$quote[^$nl$quote]*\$" + [[ ${_ble_edit_str::index} =~ $rex ]] || return 1 + ((ret=index-${#BASH_REMATCH})) + return 0 +} +function ble/keymap:vi/text-object/quote.impl { + local arg=$1 flag=$2 reg=$3 type=$4 + local ret quote=${type:1} + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + if ble/keymap:vi/text-object:quote/.xmap; then + ble/keymap:vi/adjust-command-mode + return 0 + else + ble/widget/vi-command/bell + return 1 + fi + fi + local beg= end= + if [[ ${_ble_edit_str:_ble_edit_ind:1} == "$quote" ]]; then + ble-edit/content/find-logical-bol; local bol=$ret + ble/string#count-char "${_ble_edit_str:bol:_ble_edit_ind-bol}" "$quote" + if ((ret%2==1)); then + ((end=_ble_edit_ind+1)) + ble/keymap:vi/text-object:quote/.prev && beg=$ret + else + ((beg=_ble_edit_ind)) + ble/keymap:vi/text-object:quote/.next && end=$((ret+1)) + fi + elif ble/keymap:vi/text-object:quote/.prev && beg=$ret; then + ble/keymap:vi/text-object:quote/.next && end=$((ret+1)) + elif ble/keymap:vi/text-object:quote/.next && beg=$ret; then + ble/keymap:vi/text-object:quote/.next $((beg+1)) && end=$((ret+1)) + fi + if [[ $beg && $end ]]; then + [[ $type == i* || arg -gt 1 ]] && ((beg++,end--)) + ble/widget/vi-command/exclusive-range.impl "$beg" "$end" "$flag" "$reg" + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/keymap:vi/text-object:quote/.expand-xmap-range { + local inclusive=$1 + ((end++)) + if ((inclusive==2)); then + local rex + rex=$'^[ \t]+'; [[ ${_ble_edit_str:end} =~ $rex ]] && ((end+=${#BASH_REMATCH})) + elif ((inclusive==0&&end-beg>2)); then + ((beg++,end--)) + fi +} +function ble/keymap:vi/text-object:quote/.xmap { + local min=$_ble_edit_ind max=$_ble_edit_mark + ((min>max)) && local min=$max max=$min + [[ ${_ble_edit_str:min:max+1-min} == *$'\n'* ]] && return 1 + local inclusive=0 + if [[ $type == a* ]]; then + inclusive=2 + elif ((arg>1)); then + inclusive=1 + fi + local ret + if ((_ble_edit_ind==_ble_edit_mark)); then + ble/keymap:vi/text-object:quote/.prev $((_ble_edit_ind+1)) || + ble/keymap:vi/text-object:quote/.next $((_ble_edit_ind+1)) || return 1 + local beg=$ret + ble/keymap:vi/text-object:quote/.next $((beg+1)) || return 1 + local end=$ret + ble/keymap:vi/text-object:quote/.expand-xmap-range "$inclusive" + _ble_edit_mark=$beg + _ble_edit_ind=$((end-1)) + return 0 + elif ((_ble_edit_ind>_ble_edit_mark)); then + local updates_mark= + if [[ ${_ble_edit_str:_ble_edit_ind:1} == "$quote" ]]; then + ble/keymap:vi/text-object:quote/.next $((_ble_edit_ind+1)) || return 1; local beg=$ret + if ble/keymap:vi/text-object:quote/.next $((beg+1)); then + local end=$ret + else + local end=$beg beg=$_ble_edit_ind + fi + else + ble-edit/content/find-logical-bol; local bol=$ret + ble/string#count-char "${_ble_edit_str:bol:_ble_edit_ind-bol}" "$quote" + if ((ret%2==0)); then + ble/keymap:vi/text-object:quote/.next $((_ble_edit_ind+1)) || return 1; local beg=$ret + ble/keymap:vi/text-object:quote/.next $((beg+1)) || return 1; local end=$ret + else + ble/keymap:vi/text-object:quote/.prev "$_ble_edit_ind" || return 1; local beg=$ret + ble/keymap:vi/text-object:quote/.next $((_ble_edit_ind+1)) || return 1; local end=$ret + fi + local i1=$((_ble_edit_mark?_ble_edit_mark-1:0)) + [[ ${_ble_edit_str:i1:_ble_edit_ind-i1} != *"$quote"* ]] && updates_mark=1 + fi + ble/keymap:vi/text-object:quote/.expand-xmap-range "$inclusive" + [[ $updates_mark ]] && _ble_edit_mark=$beg + _ble_edit_ind=$((end-1)) + return 0 + else + ble-edit/content/find-logical-bol; local bol=$ret nl=$'\n' + local rex="^([^$nl$quote]*$quote[^$nl$quote]*$quote)*[^$nl$quote]*$quote" + [[ ${_ble_edit_str:bol:_ble_edit_ind-bol} =~ $rex ]] || return 1 + local beg=$((bol+${#BASH_REMATCH}-1)) + ble/keymap:vi/text-object:quote/.next $((beg+1)) || return 1 + local end=$ret + ble/keymap:vi/text-object:quote/.expand-xmap-range "$inclusive" + [[ ${_ble_edit_str:_ble_edit_ind:_ble_edit_mark+2-_ble_edit_ind} != *"$quote"* ]] && _ble_edit_mark=$((end-1)) + _ble_edit_ind=$beg + return 0 + fi +} +function ble/keymap:vi/text-object/block.impl { + local arg=$1 flag=$2 reg=$3 type=$4 + local ret paren=${type:1} lparen=${type:1:1} rparen=${type:2:1} + local axis=$_ble_edit_ind + [[ ${_ble_edit_str:axis:1} == "$lparen" ]] && ((axis++)) + local count=$arg beg=$axis + while ble/string#last-index-of-chars "$_ble_edit_str" "$paren" "$beg"; do + beg=$ret + if [[ ${_ble_edit_str:beg:1} == "$lparen" ]]; then + ((--count==0)) && break + else + ((++count)) + fi + done + if ((count)); then + ble/widget/vi-command/bell + return 1 + fi + local count=$arg end=$axis + while ble/string#index-of-chars "$_ble_edit_str" "$paren" "$end"; do + end=$((ret+1)) + if [[ ${_ble_edit_str:end-1:1} == "$rparen" ]]; then + ((--count==0)) && break + else + ((++count)) + fi + done + if ((count)); then + ble/widget/vi-command/bell + return 1 + fi + local linewise= + if [[ $type == *i* ]]; then + ((beg++,end--)) + [[ ${_ble_edit_str:beg:1} == $'\n' ]] && ((beg++)) + ((beg<end)) && ble-edit/content/bolp "$end" && ((end--)) + ((beg<end)) && ble-edit/content/bolp "$beg" && ble-edit/content/eolp "$end" && linewise=1 + fi + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + _ble_edit_mark=$beg + ble/widget/vi-command/exclusive-goto.impl "$end" + elif [[ $linewise ]]; then + ble/widget/vi-command/linewise-range.impl "$beg" "$end" "$flag" "$reg" goto_bol + else + ble/widget/vi-command/exclusive-range.impl "$beg" "$end" "$flag" "$reg" + fi +} +function ble/keymap:vi/text-object:tag/.find-end-tag { + local ifs=$_ble_term_IFS ret rex + rex="^<([^$ifs/>!]+)"; [[ ${_ble_edit_str:beg} =~ $rex ]] || return 1 + ble/string#escape-for-extended-regex "${BASH_REMATCH[1]}"; local tagname=$ret + rex="^</?$tagname([$ifs]+([^>]*[^/])?)?>" + end=$beg + local count=0 + while ble/string#index-of-chars "$_ble_edit_str" '<' "$end" && end=$((ret+1)); do + [[ ${_ble_edit_str:end-1} =~ $rex ]] || continue + ((end+=${#BASH_REMATCH}-1)) + if [[ ${BASH_REMATCH::2} == '</' ]]; then + ((--count==0)) && return 0 + else + ((++count)) + fi + done + return 1 +} +function ble/keymap:vi/text-object/tag.impl { + local arg=$1 flag=$2 reg=$3 type=$4 + local ret rex + local pivot=$_ble_edit_ind ret=$_ble_edit_ind + if [[ ${_ble_edit_str:ret:1} == '<' ]] || ble/string#last-index-of-chars "${_ble_edit_str::_ble_edit_ind}" '<>'; then + if rex='^<[^/][^>]*>' && [[ ${_ble_edit_str:ret} =~ $rex ]]; then + ((pivot=ret+${#BASH_REMATCH})) + else + ((pivot=ret+1)) + fi + fi + local ifs=$_ble_term_IFS + local beg=$pivot count=$arg + rex="<([^$ifs/>!]+([$ifs]+([^>]*[^/])?)?|/[^>]*)>\$" + while ble/string#last-index-of-chars "${_ble_edit_str::beg}" '>' && beg=$ret; do + [[ ${_ble_edit_str::beg+1} =~ $rex ]] || continue + ((beg-=${#BASH_REMATCH}-1)) + if [[ ${BASH_REMATCH::2} == '</' ]]; then + ((++count)) + else + if ((--count==0)); then + if ble/keymap:vi/text-object:tag/.find-end-tag "$beg" && ((_ble_edit_ind<end)); then + break + else + ((count++)) + fi + fi + fi + done + if ((count)); then + ble/widget/vi-command/bell + return 1 + fi + if [[ $type == i* ]]; then + rex='^<[^>]*>'; [[ ${_ble_edit_str:beg:end-beg} =~ $rex ]] && ((beg+=${#BASH_REMATCH})) + rex='<[^>]*>$'; [[ ${_ble_edit_str:beg:end-beg} =~ $rex ]] && ((end-=${#BASH_REMATCH})) + fi + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + _ble_edit_mark=$beg + ble/widget/vi-command/exclusive-goto.impl "$end" + else + ble/widget/vi-command/exclusive-range.impl "$beg" "$end" "$flag" "$reg" + fi +} +function ble/keymap:vi/text-object:sentence/.beg { + beg= is_interval= + local pivot=$_ble_edit_ind rex= + if ble-edit/content/bolp && ble-edit/content/eolp; then + if rex=$'^\n+[^\n]'; [[ ${_ble_edit_str:pivot} =~ $rex ]]; then + beg=$((pivot+${#BASH_REMATCH}-2)) + else + if rex=$'\n+$'; [[ ${_ble_edit_str::pivot} =~ $rex ]]; then + ((pivot-=${#BASH_REMATCH})) + fi + fi + fi + if [[ ! $beg ]]; then + rex="^.*((^$LF?|$LF$LF)([ $HT]*)|[.!?][])'\"]*([ $HT$LF]+))" + if [[ ${_ble_edit_str::pivot+1} =~ $rex ]]; then + beg=${#BASH_REMATCH} + if ((pivot<beg)); then + local rematch34=${BASH_REMATCH[3]}${BASH_REMATCH[4]} + if [[ $rematch34 ]]; then + beg=$((pivot+1-${#rematch34})) is_interval=1 + else + beg=$pivot + fi + fi + else + beg=0 + fi + fi +} +function ble/keymap:vi/text-object:sentence/.next { + if [[ $is_interval ]]; then + is_interval= + local rex=$'[ \t]*((\n[ \t]+)*\n[ \t]*)?' + [[ ${_ble_edit_str:end} =~ $rex ]] + local index=$((end+${#BASH_REMATCH})) + ((end<index)) && [[ ${_ble_edit_str:index-1:1} == $'\n' ]] && ((index--)) + ((end=index)) + else + is_interval=1 + if local rex=$'^\n+'; [[ ${_ble_edit_str:end} =~ $rex ]]; then + ((end+=${#BASH_REMATCH})) + elif rex="(([.!?][])\"']*)[ $HT$LF]|$LF$LF).*\$"; [[ ${_ble_edit_str:end} =~ $rex ]]; then + local rematch2=${BASH_REMATCH[2]} + end=$((${#_ble_edit_str}-${#BASH_REMATCH}+${#rematch2})) + else + local index=${#_ble_edit_str} + ((end<index)) && [[ ${_ble_edit_str:index-1:1} == $'\n' ]] && ((index--)) + ((end=index)) + fi + fi +} +function ble/keymap:vi/text-object/sentence.impl { + local arg=$1 flag=$2 reg=$3 type=$4 + local LF=$'\n' HT=$'\t' + local rex + local beg is_interval + ble/keymap:vi/text-object:sentence/.beg + local end=$beg i n=$arg + [[ $type != i* ]] && ((n*=2)) + for ((i=0;i<n;i++)); do + ble/keymap:vi/text-object:sentence/.next + done + ((beg<end)) && [[ ${_ble_edit_str:end-1:1} == $'\n' ]] && ((end--)) + if [[ $type != i* && ! $is_interval ]]; then + local ifs=$_ble_term_IFS + if ((end)) && [[ ${_ble_edit_str:end-1:1} != ["$ifs"] ]]; then + rex="^.*(^$LF?|$LF$LF|[.!?][])'\"]*([ $HT$LF]))([ $HT$LF]*)\$" + if [[ ${_ble_edit_str::beg} =~ $rex ]]; then + local rematch2=${BASH_REMATCH[2]} + local rematch3=${BASH_REMATCH[3]} + ((beg-=${#rematch2}+${#rematch3})) + [[ ${_ble_edit_str:beg:1} == $'\n' ]] && ((beg++)) + fi + fi + fi + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + _ble_edit_mark=$beg + ble/widget/vi-command/exclusive-goto.impl "$end" + elif ble-edit/content/bolp "$beg" && [[ ${_ble_edit_str:end:1} == $'\n' ]]; then + ble/widget/vi-command/linewise-range.impl "$beg" "$end" "$flag" "$reg" goto_bol + else + ble/widget/vi-command/exclusive-range.impl "$beg" "$end" "$flag" "$reg" + fi +} +function ble/keymap:vi/text-object/paragraph.impl { + local arg=$1 flag=$2 reg=$3 type=$4 + local rex ret + local beg= empty_start= + ble-edit/content/find-logical-bol; local bol=$ret + ble-edit/content/find-non-space "$bol"; local nol=$ret + if rex=$'[ \t]*(\n|$)' ble-edit/content/eolp "$nol"; then + empty_start=1 + rex=$'(^|\n)([ \t]*\n)*$' + [[ ${_ble_edit_str::bol} =~ $rex ]] + local rematch1=${BASH_REMATCH[1]} # Note: for bash-3.1 ${#arr[n]} bug + ((beg=bol-(${#BASH_REMATCH}-${#rematch1}))) + else + if rex=$'^(.*\n)?[ \t]*\n'; [[ ${_ble_edit_str::bol} =~ $rex ]]; then + ((beg=${#BASH_REMATCH})) + else + ((beg=0)) + fi + fi + local end=$beg + local rex_empty_line=$'([ \t]*\n|[ \t]+$)' rex_paragraph_line=$'([ \t]*[^ \t\n][^\n]*(\n|$))' + if [[ $type == i* ]]; then + rex="$rex_empty_line+|$rex_paragraph_line+" + elif [[ $empty_start ]]; then + rex="$rex_empty_line*$rex_paragraph_line+" + else + rex="$rex_paragraph_line+$rex_empty_line*" + fi + local i + for ((i=0;i<arg;i++)); do + if [[ ${_ble_edit_str:end} =~ $rex ]]; then + ((end+=${#BASH_REMATCH})) + else + ble/widget/vi-command/bell + return 1 + fi + done + if [[ $type != i* && ! $empty_start ]]; then + if rex=$'(^|\n)[ \t]*\n$'; ! [[ ${_ble_edit_str::end} =~ $rex ]]; then + if rex=$'(^|\n)([ \t]*\n)*$'; [[ ${_ble_edit_str::beg} =~ $rex ]]; then + local rematch1=${BASH_REMATCH[1]} + ((beg-=${#BASH_REMATCH}-${#rematch1})) + fi + fi + fi + ((beg<end)) && [[ ${_ble_edit_str:end-1:1} == $'\n' ]] && ((end--)) + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + _ble_edit_mark=$beg + ble/widget/vi-command/exclusive-goto.impl "$end" + else + ble/widget/vi-command/linewise-range.impl "$beg" "$end" "$flag" "$reg" + fi +} +function ble/keymap:vi/text-object.impl { + local arg=$1 flag=$2 reg=$3 type=$4 + case "$type" in + ([ia][wW]) ble/keymap:vi/text-object/word.impl "$arg" "$flag" "$reg" "$type" ;; + ([ia][\"\'\`]) ble/keymap:vi/text-object/quote.impl "$arg" "$flag" "$reg" "$type" ;; + ([ia]['b()']) ble/keymap:vi/text-object/block.impl "$arg" "$flag" "$reg" "${type::1}()" ;; + ([ia]['B{}']) ble/keymap:vi/text-object/block.impl "$arg" "$flag" "$reg" "${type::1}{}" ;; + ([ia]['<>']) ble/keymap:vi/text-object/block.impl "$arg" "$flag" "$reg" "${type::1}<>" ;; + ([ia]['][']) ble/keymap:vi/text-object/block.impl "$arg" "$flag" "$reg" "${type::1}[]" ;; + ([ia]t) ble/keymap:vi/text-object/tag.impl "$arg" "$flag" "$reg" "$type" ;; + ([ia]s) ble/keymap:vi/text-object/sentence.impl "$arg" "$flag" "$reg" "$type" ;; + ([ia]p) ble/keymap:vi/text-object/paragraph.impl "$arg" "$flag" "$reg" "$type" ;; + (*) + ble/widget/vi-command/bell + return 1;; + esac +} +function ble/keymap:vi/text-object.hook { + local key=$1 + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + if ! ble-decode-key/ischar "$key"; then + ble/widget/vi-command/bell + return 1 + fi + local ret; ble/util/c2s "$key" + local type=$_ble_keymap_vi_text_object$ret + ble/keymap:vi/text-object.impl "$ARG" "$FLAG" "$REG" "$type" + return 0 +} +function ble/keymap:vi/.check-text-object { + local n=${#KEYS[@]}; ((n&&n--)) + ble-decode-key/ischar "${KEYS[n]}" || return 1 + local ret; ble/util/c2s "${KEYS[n]}"; local c=$ret + [[ $c == [ia] ]] || return 1 + [[ $_ble_keymap_vi_opfunc || $_ble_decode_keymap == vi_[xs]map ]] || return 1 + _ble_keymap_vi_text_object=$c + _ble_decode_key__hook=ble/keymap:vi/text-object.hook + return 0 +} +function ble/widget/vi-command/text-object { + ble/keymap:vi/.check-text-object && return 0 + ble/widget/vi-command/bell + return 1 +} +_ble_keymap_vi_commandline_history=() +_ble_keymap_vi_commandline_history_edit=() +_ble_keymap_vi_commandline_history_dirt=() +_ble_keymap_vi_commandline_history_index=0 +_ble_keymap_vi_cmap_is_cancel_key[63|_ble_decode_Ctrl]=1 # C-? +_ble_keymap_vi_cmap_is_cancel_key[127]=1 # DEL +_ble_keymap_vi_cmap_is_cancel_key[104|_ble_decode_Ctrl]=1 # C-h +_ble_keymap_vi_cmap_is_cancel_key[8]=1 # BS +function ble/keymap:vi/commandline/before-command.hook { + if [[ ! $_ble_edit_str ]] && ((_ble_keymap_vi_cmap_is_cancel_key[KEYS[0]])); then + ble/widget/vi_cmap/cancel + ble/decode/widget/suppress-widget + fi +} +function ble/widget/vi-command/commandline { + ble/keymap:vi/clear-arg + ble/keymap:vi/async-commandline-mode ble/widget/vi-command/commandline.hook + _ble_edit_PS1=: + ble/history/set-prefix _ble_keymap_vi_commandline + _ble_keymap_vi_cmap_before_command=ble/keymap:vi/commandline/before-command.hook + return 147 +} +function ble/widget/vi-command/commandline.hook { + local command + ble/string#split-words command "$1" + local cmd="ble/widget/vi-command:${command[0]}" + if ble/is-function "$cmd"; then + "$cmd" "${command[@]:1}"; local ext=$? + else + ble/widget/vi-command/bell "unknown command $1"; local ext=1 + fi + [[ $1 ]] && _ble_keymap_vi_register[58]=/$result # ": + return "$ext" +} +function ble/widget/vi-command:w { + if [[ $1 ]]; then + ble/builtin/history -a "$1" + local file=$1 + else + ble/builtin/history -a + local file=${HISTFILE:-'~/.bash_history'} + fi + local wc + ble/util/assign wc 'ble/bin/wc "$file"' + ble/string#split-words wc "$wc" + ble/edit/info/show text "\"$file\" ${wc[0]}L, ${wc[2]}C written" + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-command:q! { + ble/widget/exit force + return 1 +} +function ble/widget/vi-command:q { + ble/widget/exit + ble/keymap:vi/adjust-command-mode # ジョブがあるときは終了しないので。 + return 1 +} +function ble/widget/vi-command:wq { + ble/widget/vi-command:w "$@" + ble/widget/exit + ble/keymap:vi/adjust-command-mode + return 1 +} +_ble_keymap_vi_search_obackward= +_ble_keymap_vi_search_ohistory= +_ble_keymap_vi_search_needle= +_ble_keymap_vi_search_activate= +_ble_keymap_vi_search_matched= +_ble_keymap_vi_search_history=() +_ble_keymap_vi_search_history_edit=() +_ble_keymap_vi_search_history_dirt=() +_ble_keymap_vi_search_history_index=0 +bleopt/declare -v keymap_vi_search_match_current '' +function ble/highlight/layer:region/mark:vi_search/get-selection { + ble/highlight/layer:region/mark:vi_char/get-selection +} +function ble/keymap:vi/search/matched { + [[ $_ble_keymap_vi_search_matched || $_ble_edit_mark_active == vi_search || $_ble_keymap_vi_search_activate ]] +} +function ble/keymap:vi/search/clear-matched { + _ble_keymap_vi_search_activate= + _ble_keymap_vi_search_matched= + [[ $_ble_edit_mark_active == vi_search ]] && _ble_edit_mark_active= +} +function ble/keymap:vi/search/invoke-search { + local needle=$1 + local dir=+; ((opt_backward)) && dir=B + local ind=$_ble_edit_ind + if ((opt_optional_next)); then + if ((!opt_backward)); then + ((_ble_edit_ind<${#_ble_edit_str}&&_ble_edit_ind++)) + fi + elif ((opt_locate)) || ! ble/keymap:vi/search/matched; then + if ((opt_locate)) || [[ $bleopt_keymap_vi_search_match_current ]]; then + if ((opt_backward)); then + ble-edit/content/eolp || ((_ble_edit_ind++)) + fi + else + if ((!opt_backward)); then + ble-edit/content/eolp || ((_ble_edit_ind++)) + fi + fi + else + if ((!opt_backward)); then + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + if ble-edit/isearch/search "$@" && ((beg==_ble_edit_ind)); then + _ble_edit_ind=$end + else + ((_ble_edit_ind<${#_ble_edit_str}&&_ble_edit_ind++)) + fi + else + ((_ble_edit_ind=_ble_edit_mark)) + ble-edit/content/eolp || ((_ble_edit_ind++)) + fi + else + dir=- + fi + fi + ble-edit/isearch/search "$needle" "$dir":regex; local ret=$? + _ble_edit_ind=$ind + return "$ret" +} +function ble/widget/vi-command/search.core { + local beg= end= is_empty_match= + if ble/keymap:vi/search/invoke-search "$needle"; then + if ((beg<end)); then + ble-edit/content/bolp "$end" || ((end--)) + _ble_edit_ind=$beg # eol 補正は search.impl 側で最後に行う + [[ $_ble_decode_keymap != vi_[xs]map ]] && _ble_edit_mark=$end + _ble_keymap_vi_search_activate=vi_search + return 0 + else + opt_history= + is_empty_match=1 + fi + fi + if ((opt_history)) && [[ $_ble_history_load_done || opt_backward -ne 0 ]]; then + ble/history/initialize + local index; ble/history/get-index + [[ $start ]] || start=$index + if ((opt_backward)); then + ((index--)) + else + ((index++)) + fi + local _ble_edit_isearch_dir=+; ((opt_backward)) && _ble_edit_isearch_dir=- + local _ble_edit_isearch_str=$needle + local isearch_ntask=$ntask + local isearch_time=0 + local isearch_progress_callback=ble-edit/isearch/.show-status-with-progress.fib + if ((opt_backward)); then + ble/history/isearch-backward-blockwise regex:progress + else + ble/history/isearch-forward regex:progress + fi; local r=$? + ble/edit/info/default + if ((r==0)); then + local new_index; ble/history/get-index -v new_index + [[ $index != "$new_index" ]] && + ble-edit/history/goto "$index" + if ((opt_backward)); then + local i=${#_ble_edit_str} + ble/keymap:vi/needs-eol-fix "$i" && ((i--)) + _ble_edit_ind=$i + else + _ble_edit_ind=0 + fi + opt_locate=1 opt_history=0 ble/widget/vi-command/search.core + return "$?" + fi + fi + if ((!opt_optional_next)); then + if [[ $is_empty_match ]]; then + ble/widget/.bell "search: empty match" + else + ble/widget/.bell "search: not found" + fi + if [[ $_ble_edit_mark_active == vi_search ]]; then + _ble_keymap_vi_search_activate=vi_search + fi + fi + return 1 +} +function ble/widget/vi-command/search.impl { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local opts=$1 needle=$2 + [[ :$opts: != *:repeat:* ]]; local opt_repeat=$? # 再検索 n N + [[ :$opts: != *:history:* ]]; local opt_history=$? # 履歴検索が有効か + [[ :$opts: != *:-:* ]]; local opt_backward=$? # 逆方向 + local opt_locate=0 + local opt_optional_next=0 + if ((opt_repeat)); then + if [[ $_ble_keymap_vi_search_needle ]]; then + needle=$_ble_keymap_vi_search_needle + ((opt_backward^=_ble_keymap_vi_search_obackward, + opt_history=_ble_keymap_vi_search_ohistory)) + else + ble/widget/vi-command/bell 'no previous search' + return 1 + fi + else + ble/keymap:vi/search/clear-matched + if [[ $needle ]]; then + _ble_keymap_vi_search_needle=$needle + _ble_keymap_vi_search_obackward=$opt_backward + _ble_keymap_vi_search_ohistory=$opt_history + elif [[ $_ble_keymap_vi_search_needle ]]; then + needle=$_ble_keymap_vi_search_needle + _ble_keymap_vi_search_obackward=$opt_backward + _ble_keymap_vi_search_ohistory=$opt_history + else + ble/widget/vi-command/bell 'no previous search' + return 1 + fi + fi + local original_ind=$_ble_edit_ind + if [[ $FLAG || $_ble_decode_keymap == vi_[xs]map ]]; then + opt_history=0 + else + local old_hindex; ble/history/get-index -v old_hindex + fi + local start= # 初めの履歴番号。search.core 内で最初に履歴を読み込んだあとで設定される。 + local ntask=$ARG + while ((ntask)); do + ble/widget/vi-command/search.core || break + ((ntask--)) + done + if [[ $FLAG ]]; then + if ((ntask)); then + _ble_keymap_vi_search_activate= + _ble_edit_ind=$original_ind + ble/keymap:vi/adjust-command-mode + return 1 + else + if ((_ble_edit_ind==original_index)); then + opt_optional_next=1 ble/widget/vi-command/search.core + fi + local index=$_ble_edit_ind + _ble_keymap_vi_search_activate= + _ble_edit_ind=$original_ind + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" nobell + fi + else + if ((ntask<ARG)); then + if ((opt_history)); then + local new_hindex; ble/history/get-index -v new_hindex + ((new_hindex==old_hindex)) + fi && ble/keymap:vi/mark/set-local-mark 96 "$original_index" # `` + if ble/keymap:vi/needs-eol-fix; then + if ((!opt_backward&&_ble_edit_ind<_ble_edit_mark)); then + ((_ble_edit_ind++)) + else + ((_ble_edit_ind--)) + fi + fi + fi + ble/keymap:vi/adjust-command-mode + return 0 + fi +} +function ble/widget/vi-command/search-forward { + ble/keymap:vi/async-commandline-mode 'ble/widget/vi-command/search.impl +:history' + _ble_edit_PS1='/' + ble/history/set-prefix _ble_keymap_vi_search + _ble_keymap_vi_cmap_before_command=ble/keymap:vi/commandline/before-command.hook + return 147 +} +function ble/widget/vi-command/search-backward { + ble/keymap:vi/async-commandline-mode 'ble/widget/vi-command/search.impl -:history' + _ble_edit_PS1='?' + ble/history/set-prefix _ble_keymap_vi_search + _ble_keymap_vi_cmap_before_command=ble/keymap:vi/commandline/before-command.hook + return 147 +} +function ble/widget/vi-command/search-repeat { + ble/widget/vi-command/search.impl repeat:+ +} +function ble/widget/vi-command/search-reverse-repeat { + ble/widget/vi-command/search.impl repeat:- +} +function ble/widget/vi-command/search-word.impl { + local opts=$1 + local rex=$'^([^[:alnum:]_\n]*)([[:alnum:]_]*)' + if ! [[ ${_ble_edit_str:_ble_edit_ind} =~ $rex ]]; then + ble/keymap:vi/clear-arg + ble/widget/vi-command/bell 'word is not found' + return 1 + fi + local end=$((_ble_edit_ind+${#BASH_REMATCH})) + local word=${BASH_REMATCH[2]} + if [[ ! ${BASH_REMATCH[1]} ]]; then + rex=$'[[:alnum:]_]+$' + [[ ${_ble_edit_str::_ble_edit_ind} =~ $rex ]] && + word=$BASH_REMATCH$word + fi + local needle=$word + rex='\<'$needle; [[ $word =~ $rex ]] && needle=$rex + rex=$needle'\>'; [[ $word =~ $rex ]] && needle=$rex + if [[ $opts == backward ]]; then + ble/widget/vi-command/search.impl -:history "$needle" + else + local original_ind=$_ble_edit_ind + _ble_edit_ind=$((end-1)) + ble/widget/vi-command/search.impl +:history "$needle" && return 0 + _ble_edit_ind=$original_ind + return 1 + fi +} +function ble/widget/vi-command/search-word-forward { + ble/widget/vi-command/search-word.impl forward +} +function ble/widget/vi-command/search-word-backward { + ble/widget/vi-command/search-word.impl backward +} +function ble/widget/vi_nmap/command-help { + ble/keymap:vi/clear-arg + ble/widget/command-help; local ext=$? + ble/keymap:vi/adjust-command-mode + return "$ext" +} +function ble/widget/vi_xmap/command-help.core { + ble/keymap:vi/clear-arg + local get_selection=ble/highlight/layer:region/mark:$_ble_edit_mark_active/get-selection + ble/is-function "$get_selection" || return 1 + local selection + "$get_selection" || return 1 + ((${#selection[*]}==2)) || return 1 + local comp_cword=0 comp_line=$_ble_edit_str comp_point=$_ble_edit_ind + local -a comp_words; comp_words=("$cmd") + local cmd=${_ble_edit_str:selection[0]:selection[1]-selection[0]} + ble/widget/command-help.impl "$cmd"; local ext=$? + ble/keymap:vi/adjust-command-mode + return "$ext" +} +function ble/widget/vi_xmap/command-help { + if ! ble/widget/vi_xmap/command-help.core; then + ble/widget/vi-command/bell + return 1 + fi +} +function ble/keymap:vi/set-up-command-map { + ble-bind -f 0 vi-command/append-arg + ble-bind -f 1 vi-command/append-arg + ble-bind -f 2 vi-command/append-arg + ble-bind -f 3 vi-command/append-arg + ble-bind -f 4 vi-command/append-arg + ble-bind -f 5 vi-command/append-arg + ble-bind -f 6 vi-command/append-arg + ble-bind -f 7 vi-command/append-arg + ble-bind -f 8 vi-command/append-arg + ble-bind -f 9 vi-command/append-arg + ble-bind -f y 'vi-command/operator y' + ble-bind -f d 'vi-command/operator d' + ble-bind -f c 'vi-command/operator c' + ble-bind -f '<' 'vi-command/operator indent-left' + ble-bind -f '>' 'vi-command/operator indent-right' + ble-bind -f '!' 'vi-command/operator filter' + ble-bind -f 'g ~' 'vi-command/operator toggle_case' + ble-bind -f 'g u' 'vi-command/operator u' + ble-bind -f 'g U' 'vi-command/operator U' + ble-bind -f 'g ?' 'vi-command/operator rot13' + ble-bind -f 'g q' 'vi-command/operator fold' + ble-bind -f 'g w' 'vi-command/operator fold-preserve-point' + ble-bind -f 'g @' 'vi-command/operator map' + ble-bind -f paste_begin vi-command/bracketed-paste + ble-bind -f 'home' vi-command/beginning-of-line + ble-bind -f '$' vi-command/forward-eol + ble-bind -f 'end' vi-command/forward-eol + ble-bind -f '^' vi-command/first-non-space + ble-bind -f '_' vi-command/first-non-space-forward + ble-bind -f '+' vi-command/forward-first-non-space + ble-bind -f 'C-m' vi-command/forward-first-non-space + ble-bind -f 'RET' vi-command/forward-first-non-space + ble-bind -f '-' vi-command/backward-first-non-space + ble-bind -f 'g 0' vi-command/beginning-of-graphical-line + ble-bind -f 'g home' vi-command/beginning-of-graphical-line + ble-bind -f 'g ^' vi-command/graphical-first-non-space + ble-bind -f 'g $' vi-command/graphical-forward-eol + ble-bind -f 'g end' vi-command/graphical-forward-eol + ble-bind -f 'g m' vi-command/middle-of-graphical-line + ble-bind -f 'g _' vi-command/last-non-space + ble-bind -f h vi-command/backward-char + ble-bind -f l vi-command/forward-char + ble-bind -f left vi-command/backward-char + ble-bind -f right vi-command/forward-char + ble-bind -f 'C-?' 'vi-command/backward-char wrap' + ble-bind -f 'DEL' 'vi-command/backward-char wrap' + ble-bind -f 'C-h' 'vi-command/backward-char wrap' + ble-bind -f 'BS' 'vi-command/backward-char wrap' + ble-bind -f SP 'vi-command/forward-char wrap' + ble-bind -f j vi-command/forward-line + ble-bind -f down vi-command/forward-line + ble-bind -f C-n vi-command/forward-line + ble-bind -f C-j vi-command/forward-line + ble-bind -f k vi-command/backward-line + ble-bind -f up vi-command/backward-line + ble-bind -f C-p vi-command/backward-line + ble-bind -f 'g j' vi-command/graphical-forward-line + ble-bind -f 'g down' vi-command/graphical-forward-line + ble-bind -f 'g k' vi-command/graphical-backward-line + ble-bind -f 'g up' vi-command/graphical-backward-line + ble-bind -f w vi-command/forward-vword + ble-bind -f W vi-command/forward-uword + ble-bind -f b vi-command/backward-vword + ble-bind -f B vi-command/backward-uword + ble-bind -f e vi-command/forward-vword-end + ble-bind -f E vi-command/forward-uword-end + ble-bind -f 'g e' vi-command/backward-vword-end + ble-bind -f 'g E' vi-command/backward-uword-end + ble-bind -f C-right vi-command/forward-vword + ble-bind -f S-right vi-command/forward-vword + ble-bind -f C-left vi-command/backward-vword + ble-bind -f S-left vi-command/backward-vword + ble-bind -f 'g o' vi-command/nth-byte + ble-bind -f '|' vi-command/nth-column + ble-bind -f H vi-command/nth-line + ble-bind -f L vi-command/nth-last-line + ble-bind -f 'g g' vi-command/history-beginning + ble-bind -f G vi-command/history-end + ble-bind -f C-home vi-command/first-nol + ble-bind -f C-end vi-command/last-eol + ble-bind -f 'f' vi-command/search-forward-char + ble-bind -f 'F' vi-command/search-backward-char + ble-bind -f 't' vi-command/search-forward-char-prev + ble-bind -f 'T' vi-command/search-backward-char-prev + ble-bind -f ';' vi-command/search-char-repeat + ble-bind -f ',' vi-command/search-char-reverse-repeat + ble-bind -f '%' 'vi-command/search-matchpair-or vi-command/percentage-line' + ble-bind -f 'C-\ C-n' nop + ble-bind -f ':' vi-command/commandline + ble-bind -f '/' vi-command/search-forward + ble-bind -f '?' vi-command/search-backward + ble-bind -f 'n' vi-command/search-repeat + ble-bind -f 'N' vi-command/search-reverse-repeat + ble-bind -f '*' vi-command/search-word-forward + ble-bind -f '#' vi-command/search-word-backward + ble-bind -f '`' 'vi-command/goto-mark' + ble-bind -f \' 'vi-command/goto-mark line' + ble-bind -c 'C-z' fg +} +function ble/widget/vi_omap/operator-rot13-or-search-backward { + if [[ $_ble_keymap_vi_opfunc == rot13 ]]; then + ble/widget/vi-command/operator rot13 + else + ble/widget/vi-command/search-backward + fi +} +function ble/widget/vi_omap/switch-visual-mode.impl { + local new_mode=$1 + local old=$_ble_keymap_vi_opfunc + [[ $old ]] || return 1 + local new=$old: + new=${new/:vi_char:/:} + new=${new/:vi_line:/:} + new=${new/:vi_block:/:} + [[ $new_mode ]] && new=$new:$new_mode + _ble_keymap_vi_opfunc=$new +} +function ble/widget/vi_omap/switch-to-charwise { + ble/widget/vi_omap/switch-visual-mode.impl vi_char +} +function ble/widget/vi_omap/switch-to-linewise { + ble/widget/vi_omap/switch-visual-mode.impl vi_line +} +function ble/widget/vi_omap/switch-to-blockwise { + ble/widget/vi_omap/switch-visual-mode.impl vi_block +} +function ble-decode/keymap:vi_omap/define { + ble/keymap:vi/set-up-command-map + ble-bind -f __default__ vi_omap/__default__ + ble-bind -f __line_limit__ nop + ble-bind -f 'ESC' vi_omap/cancel + ble-bind -f 'C-[' vi_omap/cancel + ble-bind -f 'C-c' vi_omap/cancel + ble-bind -f a vi-command/text-object + ble-bind -f i vi-command/text-object + ble-bind -f v vi_omap/switch-to-charwise + ble-bind -f V vi_omap/switch-to-linewise + ble-bind -f C-v vi_omap/switch-to-blockwise + ble-bind -f C-q vi_omap/switch-to-blockwise + ble-bind -f '~' 'vi-command/operator toggle_case' + ble-bind -f 'u' 'vi-command/operator u' + ble-bind -f 'U' 'vi-command/operator U' + ble-bind -f '?' 'vi_omap/operator-rot13-or-search-backward' + ble-bind -f 'q' 'vi-command/operator fold' +} +function ble/widget/vi-command/exit-on-empty-line { + if [[ $_ble_edit_str ]]; then + ble/widget/vi_nmap/forward-scroll + return "$?" + else + ble/widget/exit + ble/keymap:vi/adjust-command-mode # ジョブがあるときは終了しないので。 + return 1 + fi +} +function ble/widget/vi-command/show-line-info { + local index count + ble/history/get-index -v index + ble/history/get-count -v count + local hist_ratio=$(((100*index+count-1)/count))% + local hist_stat=$'!\e[32m'$index$'\e[m / \e[32m'$count$'\e[m (\e[32m'$hist_ratio$'\e[m)' + local ret + ble/string#count-char "$_ble_edit_str" $'\n'; local nline=$((ret+1)) + ble/string#count-char "${_ble_edit_str::_ble_edit_ind}" $'\n'; local iline=$((ret+1)) + local line_ratio=$(((100*iline+nline-1)/nline))% + local line_stat=$'line \e[34m'$iline$'\e[m / \e[34m'$nline$'\e[m --\e[34m'$line_ratio$'\e[m--' + ble/edit/info/show ansi "\"$hist_stat\" $line_stat" + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-command/cancel { + if [[ $_ble_keymap_vi_single_command ]]; then + _ble_keymap_vi_single_command= + _ble_keymap_vi_single_command_overwrite= + ble/keymap:vi/update-mode-name + else + local joblist; ble/util/joblist + if ((${#joblist[*]})); then + ble/array#push joblist $'Type \e[35m:q!\e[m and press \e[35m<Enter>\e[m to abandon all \e[31mjobs\e[m and exit Bash' + IFS=$'\n' builtin eval 'ble/edit/info/show ansi "${joblist[*]}"' + else + ble/edit/info/show ansi $'Type \e[35m:q\e[m and press \e[35m<Enter>\e[m to exit Bash' + fi + fi + ble/widget/vi-command/bell + return 0 +} +bleopt/declare -v keymap_vi_imap_undo '' +_ble_keymap_vi_undo_suppress= +function ble/keymap:vi/undo/add { + [[ $_ble_keymap_vi_undo_suppress ]] && return 0 + [[ $1 == more && $bleopt_keymap_vi_imap_undo != more ]] && return 0 + ble-edit/undo/add +} +function ble/widget/vi_nmap/undo { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local _ble_keymap_vi_undo_suppress=1 + ble/keymap:vi/mark/start-edit-area + if ble-edit/undo/undo "$ARG"; then + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/adjust-command-mode + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi_nmap/redo { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local _ble_keymap_vi_undo_suppress=1 + ble/keymap:vi/mark/start-edit-area + if ble-edit/undo/redo "$ARG"; then + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/adjust-command-mode + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi_nmap/revert { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local _ble_keymap_vi_undo_suppress=1 + ble/keymap:vi/mark/start-edit-area + if ble-edit/undo/revert-toggle "$ARG"; then + ble/keymap:vi/needs-eol-fix && ((_ble_edit_ind--)) + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/adjust-command-mode + else + ble/widget/vi-command/bell + return 1 + fi +} +function ble/widget/vi_nmap/increment.impl { + local delta=$1 + ((delta==0)) && return 0 + local line=${_ble_edit_str:_ble_edit_ind} + line=${line%%$'\n'*} + local rex='^([^0-9]*)[0-9]+' + if ! [[ $line =~ $rex ]]; then + [[ $line ]] && ble/widget/.bell 'number not found' + ble/keymap:vi/adjust-command-mode + return 0 + fi + local rematch1=${BASH_REMATCH[1]} + local beg=$((_ble_edit_ind+${#rematch1})) + local end=$((_ble_edit_ind+${#BASH_REMATCH})) + rex='-?[0-9]*$'; [[ ${_ble_edit_str::beg} =~ $rex ]] + ((beg-=${#BASH_REMATCH})) + local number=${_ble_edit_str:beg:end-beg} + local abs=${number#-} + if [[ $abs == 0?* ]]; then + if [[ $number == -* ]]; then + number=-$((10#0$abs)) + else + number=$((10#0$abs)) + fi + fi + ((number+=delta)) + if [[ $abs == 0?* ]]; then + local wsign=$((number<0?1:0)) + local zpad=$((wsign+${#abs}-${#number})) + if ((zpad>0)); then + local ret; ble/string#repeat 0 "$zpad" + number=${number::wsign}$ret${number:wsign} + fi + fi + ble/widget/.replace-range "$beg" "$end" "$number" + ble/keymap:vi/mark/set-previous-edit-area "$beg" $((beg+${#number})) + ble/keymap:vi/repeat/record + _ble_edit_ind=$((beg+${#number}-1)) + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi_nmap/increment { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi_nmap/increment.impl "$ARG" +} +function ble/widget/vi_nmap/decrement { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/widget/vi_nmap/increment.impl $((-ARG)) +} +function ble/widget/vi_nmap/__line_limit__.edit { + ble/keymap:vi/clear-arg + ble/widget/vi_nmap/.insert-mode + ble/keymap:vi/repeat/clear-insert + ble/widget/edit-and-execute-command.impl "$1" +} +function ble/widget/vi_nmap/__line_limit__ { + ble/widget/__line_limit__ vi_nmap/__line_limit__.edit +} +function ble-decode/keymap:vi_nmap/define { + ble/keymap:vi/set-up-command-map + ble-bind -f __default__ vi-command/decompose-meta + ble-bind -f __line_limit__ vi_nmap/__line_limit__ + ble-bind -f 'ESC' vi-command/bell + ble-bind -f 'C-[' vi-command/bell + ble-bind -f 'C-c' vi-command/cancel + ble-bind -f a vi_nmap/append-mode + ble-bind -f A vi_nmap/append-mode-at-end-of-line + ble-bind -f i vi_nmap/insert-mode + ble-bind -f insert vi_nmap/insert-mode + ble-bind -f I vi_nmap/insert-mode-at-first-non-space + ble-bind -f 'g I' vi_nmap/insert-mode-at-beginning-of-line + ble-bind -f o vi_nmap/insert-mode-at-forward-line + ble-bind -f O vi_nmap/insert-mode-at-backward-line + ble-bind -f R vi_nmap/replace-mode + ble-bind -f 'g R' vi_nmap/virtual-replace-mode + ble-bind -f 'g i' vi_nmap/insert-mode-at-previous-point + ble-bind -f '~' vi_nmap/forward-char-toggle-case + ble-bind -f Y vi_nmap/copy-current-line + ble-bind -f S vi_nmap/kill-current-line-and-insert + ble-bind -f D vi_nmap/kill-forward-line + ble-bind -f C vi_nmap/kill-forward-line-and-insert + ble-bind -f p vi_nmap/paste-after + ble-bind -f P vi_nmap/paste-before + ble-bind -f x vi_nmap/kill-forward-char + ble-bind -f s vi_nmap/kill-forward-char-and-insert + ble-bind -f X vi_nmap/kill-backward-char + ble-bind -f delete vi_nmap/kill-forward-char + ble-bind -f 'r' vi_nmap/replace-char + ble-bind -f 'g r' vi_nmap/virtual-replace-char # vim で実際に試すとこの機能はない + ble-bind -f J vi_nmap/connect-line-with-space + ble-bind -f 'g J' vi_nmap/connect-line + ble-bind -f v vi_nmap/charwise-visual-mode + ble-bind -f V vi_nmap/linewise-visual-mode + ble-bind -f C-v vi_nmap/blockwise-visual-mode + ble-bind -f C-q vi_nmap/blockwise-visual-mode + ble-bind -f 'g v' vi-command/previous-visual-area + ble-bind -f 'g h' vi_nmap/charwise-select-mode + ble-bind -f 'g H' vi_nmap/linewise-select-mode + ble-bind -f 'g C-h' vi_nmap/blockwise-select-mode + ble-bind -f . vi_nmap/repeat + ble-bind -f K vi_nmap/command-help + ble-bind -f f1 vi_nmap/command-help + ble-bind -f 'C-d' vi_nmap/forward-line-scroll + ble-bind -f 'C-u' vi_nmap/backward-line-scroll + ble-bind -f 'C-e' vi_nmap/forward-scroll + ble-bind -f 'C-y' vi_nmap/backward-scroll + ble-bind -f 'C-f' vi_nmap/pagedown + ble-bind -f 'next' vi_nmap/pagedown + ble-bind -f 'C-b' vi_nmap/pageup + ble-bind -f 'prior' vi_nmap/pageup + ble-bind -f 'z t' vi_nmap/scroll-to-top-and-redraw + ble-bind -f 'z z' vi_nmap/scroll-to-center-and-redraw + ble-bind -f 'z b' vi_nmap/scroll-to-bottom-and-redraw + ble-bind -f 'z RET' vi_nmap/scroll-to-top-non-space-and-redraw + ble-bind -f 'z C-m' vi_nmap/scroll-to-top-non-space-and-redraw + ble-bind -f 'z +' vi_nmap/scroll-or-pagedown-and-redraw + ble-bind -f 'z -' vi_nmap/scroll-to-bottom-non-space-and-redraw + ble-bind -f 'z .' vi_nmap/scroll-to-center-non-space-and-redraw + ble-bind -f m vi-command/set-mark + ble-bind -f '"' vi-command/register + ble-bind -f 'C-g' vi-command/show-line-info + ble-bind -f 'q' vi_nmap/record-register + ble-bind -f '@' vi_nmap/play-register + ble-bind -f u vi_nmap/undo + ble-bind -f C-r vi_nmap/redo + ble-bind -f U vi_nmap/revert + ble-bind -f C-a vi_nmap/increment + ble-bind -f C-x vi_nmap/decrement + ble-bind -f 'Z Z' 'vi-command:q' + ble-bind -f 'Z Q' 'vi-command:q' + ble-bind -f 'C-j' 'accept-line' + ble-bind -f 'C-RET' 'accept-line' + ble-bind -f 'C-m' 'accept-single-line-or vi-command/forward-first-non-space' + ble-bind -f 'RET' 'accept-single-line-or vi-command/forward-first-non-space' + ble-bind -f 'C-l' 'clear-screen' + ble-bind -f 'C-d' 'vi-command/exit-on-empty-line' # overwrites vi_nmap/forward-scroll + ble-bind -f 'auto_complete_enter' auto-complete-enter + ble-bind -f M-left 'vi-command/backward-vword' + ble-bind -f M-right 'vi-command/forward-vword' + ble-bind -f C-delete 'vi-rlfunc/kill-word' + ble-bind -f '#' 'vi-rlfunc/insert-comment' + ble-bind -f '&' 'vi_nmap/@edit tilde-expand' +} +function ble/widget/vi-rlfunc/.is-uppercase { + local n=${#KEYS[@]} + local code=$((KEYS[n?n-1:0]&_ble_decode_MaskChar)) + ((0x41<=code&&code<=0x5a)) +} +function ble/widget/vi-rlfunc/delete-to { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi_nmap/kill-forward-line + else + ble/widget/vi-command/operator d + fi +} +function ble/widget/vi-rlfunc/change-to { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi_nmap/kill-forward-line-and-insert + else + ble/widget/vi-command/operator c + fi +} +function ble/widget/vi-rlfunc/yank-to { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi_nmap/copy-current-line + else + ble/widget/vi-command/operator y + fi +} +function ble/widget/vi-rlfunc/char-search { + local n=${#KEYS[@]} + local code=$((KEYS[n?n-1:0]&_ble_decode_MaskChar)) + ((code==0)) && return 1 + ble/util/c2s "$code" + case $ret in + ('f') ble/widget/vi-command/search-forward-char ;; + ('F') ble/widget/vi-command/search-backward-char ;; + ('t') ble/widget/vi-command/search-forward-char-prev ;; + ('T') ble/widget/vi-command/search-backward-char-prev ;; + (';') ble/widget/vi-command/search-char-repeat ;; + (',') ble/widget/vi-command/search-char-reverse-repeat ;; + (*) return 1 ;; + esac +} +function ble/widget/vi-rlfunc/next-word { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi-command/forward-uword + else + ble/widget/vi-command/forward-vword + fi +} +function ble/widget/vi-rlfunc/prev-word { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi-command/backward-uword + else + ble/widget/vi-command/backward-vword + fi +} +function ble/widget/vi-rlfunc/end-word { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi-command/forward-uword-end + else + ble/widget/vi-command/forward-vword-end + fi +} +function ble/widget/vi-rlfunc/put { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi_nmap/paste-before + else + ble/widget/vi_nmap/paste-after + fi +} +function ble/widget/vi-rlfunc/search { + local n=${#KEYS[@]} + local code=$((KEYS[n?n-1:0]&_ble_decode_MaskChar)) + if ((code==63)); then + ble/widget/vi-command/search-backward + else + ble/widget/vi-command/search-forward + fi +} +function ble/widget/vi-rlfunc/search-again { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi-command/search-reverse-repeat + else + ble/widget/vi-command/search-repeat + fi +} +function ble/widget/vi-rlfunc/subst { + if ble/widget/vi-rlfunc/.is-uppercase; then + ble/widget/vi_nmap/kill-current-line-and-insert + else + ble/widget/vi_nmap/kill-forward-char-and-insert + fi +} +function ble/widget/vi-rlfunc/kill-word { + _ble_keymap_vi_opfunc=d + ble/widget/vi-command/forward-vword-end +} +function ble/widget/vi-rlfunc/unix-line-discard { + _ble_keymap_vi_opfunc=d + ble/widget/vi-command/beginning-of-line +} +function ble/widget/vi-rlfunc/insert-comment { + local ARG FLAG REG; ble/keymap:vi/get-arg '' + ble/keymap:vi/mark/start-edit-area + ble/widget/insert-comment/.insert "$ARG" + ble/keymap:vi/mark/end-edit-area + ble/widget/vi_nmap/accept-line +} +function ble/widget/vi-rlfunc/quoted-insert-char.hook { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/keymap:vi/mark/start-edit-area + _ble_edit_arg=$ARG ble/widget/quoted-insert-char.hook + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/repeat/record + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-rlfunc/quoted-insert-char { + _ble_edit_mark_active= + _ble_decode_char__hook=ble/widget/vi-rlfunc/quoted-insert-char.hook + return 147 +} +function ble/widget/vi-rlfunc/quoted-insert.hook { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/keymap:vi/mark/start-edit-area + _ble_edit_arg=$ARG ble/widget/quoted-insert.hook + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/repeat/record + ble/keymap:vi/adjust-command-mode + return 0 +} +function ble/widget/vi-rlfunc/quoted-insert { + _ble_edit_mark_active= + _ble_decode_key__hook=ble/widget/vi-rlfunc/quoted-insert.hook + return 147 +} +function ble/widget/vi-rlfunc/eof-maybe { + if [[ ! $_ble_edit_str ]]; then + ble/widget/exit + ble/keymap:vi/adjust-command-mode # ジョブがあるときは終了しないので。 + return 1 + elif ble-edit/is-single-complete-line; then + ble/widget/vi_nmap/accept-line + else + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + ble/keymap:vi/mark/start-edit-area + _ble_edit_ind=${#_ble_edit_str} + _ble_edit_arg=$ARG + ble/widget/self-insert + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/adjust-command-mode + fi +} +function ble/widget/vi-rlfunc/yank-arg { + ble/widget/vi_nmap/append-mode + ble/keymap:vi/imap-repeat/reset + local -a KEYS; KEYS=(32) + ble/widget/self-insert + ble/util/unlocal KEYS + ble/widget/insert-last-argument + return "$?" +} +function ble/widget/vi-command/forward-byte { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local index=$_ble_edit_ind + ble/widget/.locate-forward-byte "$ARG" || [[ $FLAG ]] || ble/widget/.bell + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" +} +function ble/widget/vi-command/backward-byte { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local index=$_ble_edit_ind + ble/widget/.locate-forward-byte $((-ARG)) || [[ $FLAG ]] || ble/widget/.bell + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" +} +function ble/widget/vi_nmap/capitalize-XWORD { ble/widget/filter-word.impl XWORD ble/string#capitalize; } +function ble/widget/vi_nmap/downcase-XWORD { ble/widget/filter-word.impl XWORD ble/string#tolower; } +function ble/widget/vi_nmap/upcase-XWORD { ble/widget/filter-word.impl XWORD ble/string#toupper; } +function ble/widget/vi_nmap/@edit { + ble/keymap:vi/clear-arg + ble/keymap:vi/repeat/record + ble/keymap:vi/mark/start-edit-area + ble/widget/"$@" + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/adjust-command-mode +} +function ble/widget/vi_nmap/@adjust { + ble/keymap:vi/clear-arg + ble/widget/"$@" + ble/keymap:vi/adjust-command-mode +} +function ble/widget/vi_nmap/@motion { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local _ble_edit_ind=$_ble_edit_ind _ble_edit_arg=$ARG + if ble/widget/"$@"; then + local index=$_ble_edit_ind + ble/util/unlocal _ble_edit_ind + ble/widget/vi-command/exclusive-goto.impl "$index" "$FLAG" "$REG" nobell + else + ble/keymap:vi/adjust-command-mode + fi +} +function ble/keymap:vi/xmap/has-eol-extension { + [[ $_ble_edit_mark_active == *+ ]] +} +function ble/keymap:vi/xmap/add-eol-extension { + [[ $_ble_edit_mark_active ]] && + _ble_edit_mark_active=${_ble_edit_mark_active%+}+ +} +function ble/keymap:vi/xmap/remove-eol-extension { + [[ $_ble_edit_mark_active ]] && + _ble_edit_mark_active=${_ble_edit_mark_active%+} +} +function ble/keymap:vi/xmap/switch-type { + local suffix; [[ $_ble_edit_mark_active == *+ ]] && suffix=+ + _ble_edit_mark_active=$1$suffix +} +function ble/keymap:vi/get-graphical-rectangle { + local p=${1:-$_ble_edit_mark} q=${2:-$_ble_edit_ind} + local ret + ble-edit/content/find-logical-bol "$p"; p0=$ret + ble-edit/content/find-logical-bol "$q"; q0=$ret + local p0x p0y q0x q0y + ble/textmap#getxy.out --prefix=p0 "$p0" + ble/textmap#getxy.out --prefix=q0 "$q0" + local plx ply qlx qly + ble/textmap#getxy.cur --prefix=pl "$p" + ble/textmap#getxy.cur --prefix=ql "$q" + local prx=$plx pry=$ply qrx=$qlx qry=$qly + ble-edit/content/eolp "$p" && ((prx++)) || ble/textmap#getxy.out --prefix=pr $((p+1)) + ble-edit/content/eolp "$q" && ((qrx++)) || ble/textmap#getxy.out --prefix=qr $((q+1)) + ((ply-=p0y,qly-=q0y,pry-=p0y,qry-=q0y, + (ply<qly||ply==qly&&plx<qlx)?(lx=plx,ly=ply):(lx=qlx,ly=qly), + (pry>qry||pry==qry&&prx>qrx)?(rx=prx,ry=pry):(rx=qrx,ry=qry))) +} +function ble/keymap:vi/get-logical-rectangle { + local p=${1:-$_ble_edit_mark} q=${2:-$_ble_edit_ind} + local ret + ble-edit/content/find-logical-bol "$p"; p0=$ret + ble-edit/content/find-logical-bol "$q"; q0=$ret + ((p-=p0,q-=q0,p<=q)) || local p=$q q=$p + lx=$p rx=$((q+1)) ly=0 ry=0 +} +function ble/keymap:vi/get-rectangle { + if ble/edit/use-textmap; then + ble/keymap:vi/get-graphical-rectangle "$@" + else + ble/keymap:vi/get-logical-rectangle "$@" + fi +} +function ble/keymap:vi/get-rectangle-height { + local p0 q0 lx ly rx ry + ble/keymap:vi/get-rectangle "$@" + ble/string#count-char "${_ble_edit_str:p0:q0-p0}" $'\n' + ((ret++)) + return 0 +} +function ble/keymap:vi/extract-graphical-block-by-geometry { + local bol1=$1 bol2=$2 x1=$3 x2=$4 y1=0 y2=0 opts=$5 + ((bol1<=bol2||(bol1=$2,bol2=$1))) + [[ $x1 == *:* ]] && local x1=${x1%%:*} y1=${x1#*:} + [[ $x2 == *:* ]] && local x2=${x2%%:*} y2=${x2#*:} + local cols=$_ble_textmap_cols + local c1=$((cols*y1+x1)) c2=$((cols*y2+x2)) + sub_x1=$c1 sub_x2=$c2 + local ret index lx ly rx ly + ble-edit/content/find-logical-eol "$bol2"; local eol2=$ret + local lines; ble/string#split-lines lines "${_ble_edit_str:bol1:eol2-bol1}" + sub_ranges=() + local min_sfill=0 + local line bol=$bol1 eol bolx boly + local c1l c1r c2l c2r + for line in "${lines[@]}"; do + ((eol=bol+${#line})) + if [[ :$opts: == *:first_line:* ]] && ((${#sub_ranges[@]})); then + ble/array#push sub_ranges ::::: + elif [[ :$opts: == *:skip_middle:* ]] && ((0<${#sub_ranges[@]}&&${#sub_ranges[@]}<${#lines[@]}-1)); then + ble/array#push sub_ranges ::::: + else + ble/textmap#getxy.out --prefix=bol "$bol" + ble/textmap#hit out "$x1" $((boly+y1)) "$bol" "$eol" + local smin=$index x1l=$lx y1l=$ly x1r=$rx y1r=$ry + if ble/keymap:vi/xmap/has-eol-extension; then + local eolx eoly; ble/textmap#getxy.out --prefix=eol "$eol" + local smax=$eol x2l=$eolx y2l=$eoly x2r=$eolx y2r=$eoly + else + ble/textmap#hit out "$x2" $((boly+y2)) "$bol" "$eol" + local smax=$index x2l=$lx y2l=$ly x2r=$rx y2r=$ry + fi + local sfill=0 slpad=0 srpad=0 + local stext=${_ble_edit_str:smin:smax-smin} + if ((smin<smax)); then + ((c1l=(y1l-boly)*cols+x1l)) + if ((c1l<c1)); then + ((slpad=c1-c1l)) + ble/util/assert '! ble-edit/content/eolp "$smin"' + ((c1r=(y1r-boly)*cols+x1r)) + ble/util/assert '((c1r>c1))' || ((c1r=c1)) + ble/string#repeat ' ' $((c1r-c1)) + stext=$ret${stext:1} + fi + ((c2l=(y2l-boly)*cols+x2l)) + if ((c2l<c2)); then + if ((smax==eol)); then + ((sfill=c2-c2l)) + else + ble/string#repeat ' ' $((c2-c2l)) + stext=$stext$ret + ((smax++)) + ((c2r=(y2r-boly)*cols+x2r)) + ble/util/assert '((c2r>c2))' || ((c2r=c2)) + ((srpad=c2r-c2)) + fi + elif ((c2l>c2)); then + ((sfill=c2-c2l, + sfill<min_sfill&&(min_sfill=sfill))) + fi + else + if ((smin==eol)); then + ((sfill=c2-c1)) + elif ((c2>c1)); then + ble/string#repeat ' ' $((c2-c1)) + stext=$ret${stext:1} + ((smax++)) + ((c1l=(y1l-boly)*cols+x1l,slpad=c1-c1l)) + ((c1r=(y1r-boly)*cols+x1r,srpad=c1r-c1)) + fi + fi + ble/array#push sub_ranges "$smin:$smax:$slpad:$srpad:$sfill:$stext" + fi + ((bol=eol+1)) + done + if ((min_sfill<0)); then + local isub=${#sub_ranges[@]} + while ((isub--)); do + local sub=${sub_ranges[isub]} + local sub45=${sub#*:*:*:*:} + local sfill=${sub45%%:*} + sub_ranges[isub]=${sub::${#sub}-${#sub45}}$((sfill-min_sfill))${sub45:${#sfill}} + done + fi +} +function ble/keymap:vi/extract-graphical-block { + local opts=$3 + local p0 q0 lx ly rx ry + ble/keymap:vi/get-graphical-rectangle "$@" + ble/keymap:vi/extract-graphical-block-by-geometry "$p0" "$q0" "$lx:$ly" "$rx:$ry" "$opts" +} +function ble/keymap:vi/extract-logical-block-by-geometry { + local bol1=$1 bol2=$2 x1=$3 x2=$4 opts=$5 + ((bol1<=bol2||(bol1=$2,bol2=$1))) + sub_x1=$c1 sub_x2=$c2 + local ret min_sfill=0 + local bol=$bol1 eol smin smax slpad srpad sfill + sub_ranges=() + while :; do + ble-edit/content/find-logical-eol "$bol"; eol=$ret + slpad=0 srpad=0 sfill=0 + ((smin=bol+x1,smin>eol&&(smin=eol))) + if ble/keymap:vi/xmap/has-eol-extension; then + ((smax=eol, + sfill=bol+x2-eol, + sfill<min_sfill&&(min_sfill=sfill))) + else + ((smax=bol+x2,smax>eol&&(sfill=smax-eol,smax=eol))) + fi + local stext=${_ble_edit_str:smin:smax-smin} + ble/array#push sub_ranges "$smin:$smax:$slpad:$srpad:$sfill:$stext" + ((bol>=bol2)) && break + ble-edit/content/find-logical-bol "$bol" 1; bol=$ret + done + if ((min_sfill<0)); then + local isub=${#sub_ranges[@]} + while ((isub--)); do + local sub=${sub_ranges[isub]} + local sub45=${sub#*:*:*:*:} + local sfill=${sub45%%:*} + sub_ranges[isub]=${sub::${#sub}-${#sub45}}$((sfill-min_sfill))${sub45:${#sfill}} + done + fi +} +function ble/keymap:vi/extract-logical-block { + local opts=$3 + local p0 q0 lx ly rx ry + ble/keymap:vi/get-logical-rectangle "$@" + ble/keymap:vi/extract-logical-block-by-geometry "$p0" "$q0" "$lx" "$rx" "$opts" +} +function ble/keymap:vi/extract-block { + if ble/edit/use-textmap; then + ble/keymap:vi/extract-graphical-block "$@" + else + ble/keymap:vi/extract-logical-block "$@" + fi +} +function ble/highlight/layer:region/mark:vi_char/get-selection { + local rmin rmax + if ((_ble_edit_mark<_ble_edit_ind)); then + rmin=$_ble_edit_mark rmax=$_ble_edit_ind + else + rmin=$_ble_edit_ind rmax=$_ble_edit_mark + fi + ble-edit/content/eolp "$rmax" || ((rmax++)) + selection=("$rmin" "$rmax") +} +function ble/highlight/layer:region/mark:vi_line/get-selection { + local rmin rmax + if ((_ble_edit_mark<_ble_edit_ind)); then + rmin=$_ble_edit_mark rmax=$_ble_edit_ind + else + rmin=$_ble_edit_ind rmax=$_ble_edit_mark + fi + local ret + ble-edit/content/find-logical-bol "$rmin"; rmin=$ret + ble-edit/content/find-logical-eol "$rmax"; rmax=$ret + selection=("$rmin" "$rmax") +} +function ble/highlight/layer:region/mark:vi_block/get-selection { + local sub_ranges sub_x1 sub_x2 + ble/keymap:vi/extract-block + selection=() + local sub + for sub in "${sub_ranges[@]}"; do + ble/string#split sub : "$sub" + ((sub[0]<sub[1])) || continue + ble/array#push selection "${sub[0]}" "${sub[1]}" + done +} +function ble/highlight/layer:region/mark:vi_char+/get-selection { + ble/highlight/layer:region/mark:vi_char/get-selection +} +function ble/highlight/layer:region/mark:vi_line+/get-selection { + ble/highlight/layer:region/mark:vi_line/get-selection +} +function ble/highlight/layer:region/mark:vi_block+/get-selection { + ble/highlight/layer:region/mark:vi_block/get-selection +} +function ble/highlight/layer:region/mark:vi_char/get-face { [[ $_ble_edit_overwrite_mode ]] && face=region_target; } +function ble/highlight/layer:region/mark:vi_char+/get-face { ble/highlight/layer:region/mark:vi_char/get-face; } +function ble/highlight/layer:region/mark:vi_line/get-face { ble/highlight/layer:region/mark:vi_char/get-face; } +function ble/highlight/layer:region/mark:vi_line+/get-face { ble/highlight/layer:region/mark:vi_char/get-face; } +function ble/highlight/layer:region/mark:vi_block/get-face { ble/highlight/layer:region/mark:vi_char/get-face; } +function ble/highlight/layer:region/mark:vi_block+/get-face { ble/highlight/layer:region/mark:vi_char/get-face; } +_ble_keymap_vi_xmap_prev_edit=vi_char:1:1 +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_xmap_prev_edit +function ble/widget/vi_xmap/.save-visual-state { + local nline nchar mark_type=${_ble_edit_mark_active%+} + if [[ $mark_type == vi_block ]]; then + local p0 q0 lx rx ly ry + if ble/edit/use-textmap; then + local cols=$_ble_textmap_cols + ble/keymap:vi/get-graphical-rectangle + ((lx+=ly*cols,rx+=ry*cols)) + else + ble/keymap:vi/get-logical-rectangle + fi + nchar=$((rx-lx)) + local ret + ((p0<=q0)) || local p0=$q0 q0=$p0 + ble/string#count-char "${_ble_edit_str:p0:q0-p0}" $'\n' + nline=$((ret+1)) + else + local ret + local p=$_ble_edit_mark q=$_ble_edit_ind + ((p<=q)) || local p=$q q=$p + ble/string#count-char "${_ble_edit_str:p:q-p}" $'\n' + nline=$((ret+1)) + local base + if ((nline==1)) && [[ $mark_type != vi_line ]]; then + base=$p + else + ble-edit/content/find-logical-bol "$q"; base=$ret + fi + if ble/edit/use-textmap; then + local cols=$_ble_textmap_cols + local bx by x y + ble/textmap#getxy.cur --prefix=b "$base" + ble/textmap#getxy.cur "$q" + nchar=$((x-bx+(y-by)*cols+1)) + else + nchar=$((q-base+1)) + fi + fi + _ble_keymap_vi_xmap_prev_edit=$_ble_edit_mark_active:$nchar:$nline +} +function ble/widget/vi_xmap/.restore-visual-state { + local arg=$1; ((arg>0)) || arg=1 + local prev; ble/string#split prev : "$_ble_keymap_vi_xmap_prev_edit" + _ble_edit_mark_active=${prev[0]:-vi_char} + local nchar=${prev[1]:-1} + local nline=${prev[2]:-1} + ((nchar<1&&(nchar=1),nline<1&&(nline=1))) + local is_x_relative=0 + if [[ ${_ble_edit_mark_active%+} == vi_block ]]; then + ((is_x_relative=1,nchar*=arg,nline*=arg)) + elif [[ ${_ble_edit_mark_active%+} == vi_line ]]; then + ((nline*=arg,is_x_relative=1,nchar=1)) + else + ((nline==1?(is_x_relative=1,nchar*=arg):(nline*=arg))) + fi + ((nchar--,nline--)) + local index ret + ble-edit/content/find-logical-bol "$_ble_edit_ind" 0; local b1=$ret + ble-edit/content/find-logical-bol "$_ble_edit_ind" "$nline"; local b2=$ret + ble-edit/content/find-logical-eol "$b2"; local e2=$ret + if ble/keymap:vi/xmap/has-eol-extension; then + index=$e2 + elif ble/edit/use-textmap; then + local cols=$_ble_textmap_cols + local b1x b1y b2x b2y x y + ble/textmap#getxy.out --prefix=b1 "$b1" + ble/textmap#getxy.out --prefix=b2 "$b2" + if ((is_x_relative)); then + ble/textmap#getxy.out "$_ble_edit_ind" + local c=$((x+(y-b1y)*cols+nchar)) + else + local c=$nchar + fi + ((y=c/cols,x=c%cols)) + local lx ly rx ry + ble/textmap#hit out "$x" $((b2y+y)) "$b2" "$e2" + else + local c=$((is_x_relative?_ble_edit_ind-b1+nchar:nchar)) + ((index=b2+c,index>e2&&(index=e2))) + fi + _ble_edit_mark=$_ble_edit_ind + _ble_edit_ind=$index +} +_ble_keymap_vi_xmap_prev_visual= +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_xmap_prev_visual +function ble/keymap:vi/xmap/set-previous-visual-area { + local beg end + local mark_type=${_ble_edit_mark_active%+} + if [[ $mark_type == vi_block ]]; then + local sub_ranges sub_x1 sub_x2 + ble/keymap:vi/extract-block + local nrange=${#sub_ranges[*]} + ((nrange)) || return 1 + local beg=${sub_ranges[0]%%:*} + local sub2_slice1=${sub_ranges[nrange-1]#*:} + local end=${sub2_slice1%%:*} + ((beg<end)) && ! ble-edit/content/bolp "$end" && ((end--)) + else + local beg=$_ble_edit_mark end=$_ble_edit_ind + ((beg<=end)) || local beg=$end end=$beg + if [[ $mark_type == vi_line ]]; then + local ret + ble-edit/content/find-logical-bol "$beg"; beg=$ret + ble-edit/content/find-logical-eol "$end"; end=$ret + ble-edit/content/bolp "$end" || ((end--)) + fi + fi + _ble_keymap_vi_xmap_prev_visual=$_ble_edit_mark_active + ble/keymap:vi/mark/set-local-mark 60 "$beg" # `< + ble/keymap:vi/mark/set-local-mark 62 "$end" # `> +} +function ble/widget/vi-command/previous-visual-area { + local mark=$_ble_keymap_vi_xmap_prev_visual + local ret beg= end= + ble/keymap:vi/mark/get-local-mark 60 && beg=$ret # `< + ble/keymap:vi/mark/get-local-mark 62 && end=$ret # `> + [[ $beg && $end ]] || return 1 + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + ble/keymap:vi/clear-arg + ble/keymap:vi/xmap/set-previous-visual-area + _ble_edit_ind=$end + _ble_edit_mark=$beg + _ble_edit_mark_active=$mark + ble/keymap:vi/update-mode-name + else + ble/keymap:vi/clear-arg + ble/widget/vi-command/visual-mode.impl vi_xmap "$mark" + _ble_edit_ind=$end + _ble_edit_mark=$beg + fi + return 0 +} +function ble/widget/vi-command/visual-mode.impl { + local keymap=$1 visual_type=$2 + local ARG FLAG REG; ble/keymap:vi/get-arg 0 + if [[ $FLAG ]]; then + ble/widget/vi-command/bell + return 1 + fi + _ble_edit_overwrite_mode= + _ble_edit_mark=$_ble_edit_ind + _ble_edit_mark_active=$visual_type + _ble_keymap_vi_xmap_insert_data= # ※矩形挿入の途中で更に xmap に入ったときはキャンセル + ((ARG)) && ble/widget/vi_xmap/.restore-visual-state "$ARG" + ble/decode/keymap/push "$keymap" + ble/keymap:vi/update-mode-name + return 0 +} +function ble/widget/vi_nmap/charwise-visual-mode { + ble/widget/vi-command/visual-mode.impl vi_xmap vi_char +} +function ble/widget/vi_nmap/linewise-visual-mode { + ble/widget/vi-command/visual-mode.impl vi_xmap vi_line +} +function ble/widget/vi_nmap/blockwise-visual-mode { + ble/widget/vi-command/visual-mode.impl vi_xmap vi_block +} +function ble/widget/vi_nmap/charwise-select-mode { + ble/widget/vi-command/visual-mode.impl vi_smap vi_char +} +function ble/widget/vi_nmap/linewise-select-mode { + ble/widget/vi-command/visual-mode.impl vi_smap vi_line +} +function ble/widget/vi_nmap/blockwise-select-mode { + ble/widget/vi-command/visual-mode.impl vi_smap vi_block +} +function ble/widget/vi_xmap/exit { + if [[ $_ble_decode_keymap == vi_[xs]map ]]; then + ble/keymap:vi/xmap/set-previous-visual-area + _ble_edit_mark_active= + ble/decode/keymap/pop + ble/keymap:vi/update-mode-name + ble/keymap:vi/adjust-command-mode + fi + return 0 +} +function ble/widget/vi_xmap/cancel { + _ble_keymap_vi_single_command= + _ble_keymap_vi_single_command_overwrite= + ble-edit/content/nonbol-eolp && ((_ble_edit_ind--)) + ble/widget/vi_xmap/exit +} +function ble/widget/vi_xmap/switch-visual-mode.impl { + local visual_type=$1 + local ARG FLAG REG; ble/keymap:vi/get-arg 0 + if [[ $FLAG ]]; then + ble/widget/.bell + return 1 + fi + if [[ ${_ble_edit_mark_active%+} == "$visual_type" ]]; then + ble/widget/vi_xmap/cancel + else + ble/keymap:vi/xmap/switch-type "$visual_type" + ble/keymap:vi/update-mode-name + return 0 + fi +} +function ble/widget/vi_xmap/switch-to-charwise { + ble/widget/vi_xmap/switch-visual-mode.impl vi_char +} +function ble/widget/vi_xmap/switch-to-linewise { + ble/widget/vi_xmap/switch-visual-mode.impl vi_line +} +function ble/widget/vi_xmap/switch-to-blockwise { + ble/widget/vi_xmap/switch-visual-mode.impl vi_block +} +function ble/widget/vi_xmap/switch-to-select { + if [[ $_ble_decode_keymap == vi_xmap ]]; then + ble/decode/keymap/pop + ble/decode/keymap/push vi_smap + ble/keymap:vi/update-mode-name + fi +} +function ble/widget/vi_xmap/switch-to-visual { + if [[ $_ble_decode_keymap == vi_smap ]]; then + ble/decode/keymap/pop + ble/decode/keymap/push vi_xmap + ble/keymap:vi/update-mode-name + fi +} +function ble/widget/vi_xmap/switch-to-visual-blockwise { + if [[ $_ble_decode_keymap == vi_smap ]]; then + ble/decode/keymap/pop + ble/decode/keymap/push vi_xmap + fi + if [[ ${_ble_edit_mark_active%+} != vi_block ]]; then + ble/widget/vi_xmap/switch-to-blockwise + else + xble/keymap:vi/update-mode-name + fi +} +bleopt/declare -v keymap_vi_keymodel '' +function ble/widget/vi_smap/@nomarked { + [[ ,$bleopt_keymap_vi_keymodel, == *,stopsel,* ]] && + ble/widget/vi_xmap/exit + ble/widget/"$@" +} +function ble/widget/vi_smap/self-insert { + ble/widget/vi-command/operator c + ble/widget/self-insert +} +function ble/widget/vi_xmap/exchange-points { + ble/keymap:vi/xmap/remove-eol-extension + ble/widget/exchange-point-and-mark + return 0 +} +function ble/widget/vi_xmap/exchange-boundaries { + if [[ ${_ble_edit_mark_active%+} == vi_block ]]; then + ble/keymap:vi/xmap/remove-eol-extension + local sub_ranges sub_x1 sub_x2 + ble/keymap:vi/extract-block '' '' skip_middle + local nline=${#sub_ranges[@]} + ble/util/assert '((nline))' + local data1; ble/string#split data1 : "${sub_ranges[0]}" + local lpos1=${data1[0]} rpos1=$((data1[4]?data1[1]:data1[1]-1)) + if ((nline==1)); then + local lpos2=$lpos1 rpos2=$rpos1 + else + local data2; ble/string#split data2 : "${sub_ranges[nline-1]}" + local lpos2=${data2[0]} rpos2=$((data2[4]?data2[1]:data2[1]-1)) + fi + if ! ((lpos2<=_ble_edit_ind&&_ble_edit_ind<=rpos2)); then + local lpos1=$lpos2 lpos2=$lpos1 + local rpos1=$rpos2 rpos2=$rpos1 + fi + _ble_edit_mark=$((_ble_edit_mark==lpos1?rpos1:lpos1)) + _ble_edit_ind=$((_ble_edit_ind==lpos2?rpos2:lpos2)) + return 0 + else + ble/widget/vi_xmap/exchange-points + fi +} +function ble/widget/vi_xmap/visual-replace-char.hook { + local key=$1 + _ble_edit_overwrite_mode= + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local ret + if [[ $FLAG ]]; then + ble/widget/.bell + return 1 + elif ((key==(_ble_decode_Ctrl|91))); then # C-[ -> cancel + return 27 + elif ! ble/keymap:vi/k2c "$key"; then + ble/widget/.bell + return 1 + fi + local c=$ret + ble/util/c2s "$c"; local s=$ret + local old_mark_active=$_ble_edit_mark_active # save + local mark_type=${_ble_edit_mark_active%+} + ble/widget/vi_xmap/.save-visual-state + ble/widget/vi_xmap/exit # Note: _ble_edit_mark_active will be cleared here + if [[ $mark_type == vi_block ]]; then + ble/util/c2w "$c"; local w=$ret + ((w<=0)) && w=1 + local sub_ranges sub_x1 sub_x2 + _ble_edit_mark_active=$old_mark_active ble/keymap:vi/extract-block + local n=${#sub_ranges[@]} + if ((n==0)); then + ble/widget/.bell + return 1 + fi + local width=$((sub_x2-sub_x1)) + local count=$((width/w)) + ble/string#repeat "$s" "$count"; local ins=$ret + local pad=$((width-count*w)) + if ((pad)); then + ble/string#repeat ' ' "$pad"; ins=$ins$ret + fi + local i=$n sub smin=0 + ble/keymap:vi/mark/start-edit-area + while ((i--)); do + ble/string#split sub : "${sub_ranges[i]}" + local smin=${sub[0]} smax=${sub[1]} + local slpad=${sub[2]} srpad=${sub[3]} sfill=${sub[4]} + local ins1=$ins + ((sfill)) && ins1=${ins1::(width-sfill)/w} + ((slpad)) && { ble/string#repeat ' ' "$slpad"; ins1=$ret$ins1; } + ((srpad)) && { ble/string#repeat ' ' "$srpad"; ins1=$ins1$ret; } + ble/widget/.replace-range "$smin" "$smax" "$ins1" + done + local beg=$smin + ble/keymap:vi/needs-eol-fix "$beg" && ((beg--)) + _ble_edit_ind=$beg + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/repeat/record + else + local beg=$_ble_edit_mark end=$_ble_edit_ind + ((beg<=end)) || local beg=$end end=$beg + if [[ $mark_type == vi_line ]]; then + ble-edit/content/find-logical-bol "$beg"; local beg=$ret + ble-edit/content/find-logical-eol "$end"; local end=$ret + else + ble-edit/content/eolp "$end" || ((end++)) + fi + local ins=${_ble_edit_str:beg:end-beg} + ins=${ins//[!$'\n']/"$s"} + ble/widget/.replace-range "$beg" "$end" "$ins" + ble/keymap:vi/needs-eol-fix "$beg" && ((beg--)) + _ble_edit_ind=$beg + ble/keymap:vi/mark/set-previous-edit-area "$beg" "$end" + ble/keymap:vi/repeat/record + fi + return 0 +} +function ble/widget/vi_xmap/visual-replace-char { + _ble_edit_overwrite_mode=R + ble/keymap:vi/async-read-char ble/widget/vi_xmap/visual-replace-char.hook +} +function ble/widget/vi_xmap/linewise-operator.impl { + local op=$1 opts=$2 + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + if [[ $FLAG ]]; then + ble/widget/.bell 'wrong keymap: xmap ではオペレータは設定されないはず' + return 1 + fi + local mark_type=${_ble_edit_mark_active%+} + local beg=$_ble_edit_mark end=$_ble_edit_ind + ((beg<=end)) || local beg=$end end=$beg + local call_operator= + if [[ :$opts: != *:force_line:* && $mark_type == vi_block ]]; then + call_operator=ble/keymap:vi/call-operator-blockwise + _ble_edit_mark_active=vi_block + [[ :$opts: == *:extend:* ]] && _ble_edit_mark_active=vi_block+ + else + call_operator=ble/keymap:vi/call-operator-linewise + _ble_edit_mark_active=vi_line + fi + local ble_keymap_vi_mark_active=$_ble_edit_mark_active + ble/widget/vi_xmap/.save-visual-state + ble/widget/vi_xmap/exit + "$call_operator" "$op" "$beg" "$end" "$ARG" "$REG"; local ext=$? + ((ext==147)) && return 147 + ((ext)) && ble/widget/.bell + ble/keymap:vi/adjust-command-mode + return "$ext" +} +function ble/widget/vi_xmap/replace-block-lines { ble/widget/vi_xmap/linewise-operator.impl c extend; } +function ble/widget/vi_xmap/delete-block-lines { ble/widget/vi_xmap/linewise-operator.impl d extend; } +function ble/widget/vi_xmap/delete-lines { ble/widget/vi_xmap/linewise-operator.impl d force_line; } +function ble/widget/vi_xmap/copy-block-or-lines { ble/widget/vi_xmap/linewise-operator.impl y; } +function ble/widget/vi_xmap/connect-line.impl { + local name=$1 + local ARG FLAG REG; ble/keymap:vi/get-arg 1 # ignored + local beg=$_ble_edit_mark end=$_ble_edit_ind + ((beg<=end)) || local beg=$end end=$beg + local ret; ble/string#count-char "${_ble_edit_str:beg:end-beg}" $'\n'; local nline=$((ret+1)) + ble/widget/vi_xmap/.save-visual-state + ble/widget/vi_xmap/exit # Note: _ble_edit_mark_active will be cleared here + _ble_edit_ind=$beg + _ble_edit_arg=$nline + _ble_keymap_vi_oparg= + _ble_keymap_vi_opfunc= + _ble_keymap_vi_reg= + "ble/widget/$name" +} +function ble/widget/vi_xmap/connect-line-with-space { + ble/widget/vi_xmap/connect-line.impl vi_nmap/connect-line-with-space +} +function ble/widget/vi_xmap/connect-line { + ble/widget/vi_xmap/connect-line.impl vi_nmap/connect-line +} +_ble_keymap_vi_xmap_insert_data= +_ble_keymap_vi_xmap_insert_dbeg=-1 +ble/array#push _ble_textarea_local_VARNAMES \ + _ble_keymap_vi_xmap_insert_data \ + _ble_keymap_vi_xmap_insert_dbeg +function ble/keymap:vi/xmap/update-dirty-range { + [[ $_ble_keymap_vi_insert_leave == ble/widget/vi_xmap/block-insert-mode.onleave ]] && + ((_ble_keymap_vi_xmap_insert_dbeg<0||beg<_ble_keymap_vi_xmap_insert_dbeg)) && + _ble_keymap_vi_xmap_insert_dbeg=$beg +} +function ble/widget/vi_xmap/block-insert-mode.impl { + local type=$1 + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local nline=${#sub_ranges[@]} + ble/util/assert '((nline))' + local index ins_x + if [[ $type == append ]]; then + local sub=${sub_ranges[0]#*:} + local smax=${sub%%:*} + index=$smax + if ble/keymap:vi/xmap/has-eol-extension; then + ins_x='$' + else + ins_x=$sub_x2 + fi + else + local sub=${sub_ranges[0]} + local smin=${sub%%:*} + index=$smin + ins_x=$sub_x1 + fi + ble/widget/vi_xmap/cancel + _ble_edit_ind=$index + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + ble/keymap:vi/mark/set-local-mark 1 "$_ble_edit_ind" + _ble_keymap_vi_xmap_insert_dbeg=-1 + local ret display_width + ble/string#count-char "${_ble_edit_str::_ble_edit_ind}" $'\n'; local iline=$ret + ble-edit/content/find-logical-bol; local bol=$ret + ble-edit/content/find-logical-eol; local eol=$ret + if ble/edit/use-textmap; then + local bx by ex ey + ble/textmap#getxy.out --prefix=b "$bol" + ble/textmap#getxy.out --prefix=e "$eol" + ((display_width=ex+_ble_textmap_cols*(ey-by))) + else + ((display_width=eol-bol)) + fi + _ble_keymap_vi_xmap_insert_data=$iline:$ins_x:$display_width:$nline + _ble_keymap_vi_insert_leave=ble/widget/vi_xmap/block-insert-mode.onleave + return 0 +} +function ble/widget/vi_xmap/block-insert-mode.onleave { + local data=$_ble_keymap_vi_xmap_insert_data + [[ $data ]] || continue + _ble_keymap_vi_xmap_insert_data= + ble/string#split data : "$data" + local ret + ble-edit/content/find-logical-bol; local bol=$ret + ble/string#count-char "${_ble_edit_str::bol}" $'\n'; ((ret==data[0])) || return 1 # 行番号 + ble/keymap:vi/mark/get-local-mark 1 || return 1; local mark=$ret # `[ + ble-edit/content/find-logical-bol "$mark"; ((bol==ret)) || return 1 # 記録行 `[ と同じか + local has_textmap= + if ble/edit/use-textmap; then + local cols=$_ble_textmap_cols + has_textmap=1 + fi + local new_width delta + ble-edit/content/find-logical-eol; local eol=$ret + if [[ $has_textmap ]]; then + local bx by ex ey + ble/textmap#getxy.out --prefix=b "$bol" + ble/textmap#getxy.out --prefix=e "$eol" + ((new_width=ex+cols*(ey-by))) + else + ((new_width=eol-bol)) + fi + ((delta=new_width-data[2])) + ((delta>0)) || return 1 # 縮んだ場合は処理しない + local x1=${data[1]} + [[ $x1 == '$' ]] && ((x1=data[2])) + ((x1>new_width&&(x1=new_width))) + if ((bol<=_ble_keymap_vi_xmap_insert_dbeg&&_ble_keymap_vi_xmap_insert_dbeg<=eol)); then + local px py + if [[ $has_textmap ]]; then + ble/textmap#getxy.out --prefix=p "$_ble_keymap_vi_xmap_insert_dbeg" + ((px+=cols*(py-by))) + else + ((px=_ble_keymap_vi_xmap_insert_dbeg-bol)) + fi + ((px>x1&&(x1=px))) + fi + local x2=$((x1+delta)) + local ins= p1 p2 + if [[ $has_textmap ]]; then + local index lx ly rx ry + ble/textmap#hit out $((x1%cols)) $((by+x1/cols)) "$bol" "$eol"; p1=$index + ble/textmap#hit out $((x2%cols)) $((by+x2/cols)) "$bol" "$eol"; p2=$index + ((lx+=(ly-by)*cols,rx+=(ry-by)*cols,lx!=rx&&p2++)) + else + ((p1=bol+x1,p2=bol+x2)) + fi + ins=${_ble_edit_str:p1:p2-p1} + local -a ins_beg=() ins_text=() + local iline=1 nline=${data[3]} strlen=${#_ble_edit_str} + for ((iline=1;iline<nline;iline++)); do + local index= lpad= + if ((eol<strlen)); then + bol=$((eol+1)) + ble-edit/content/find-logical-eol "$bol"; eol=$ret + else + bol=$eol lpad=$'\n' + fi + if [[ ${data[1]} == '$' ]]; then + index=$eol + elif [[ $has_textmap ]]; then + ble/textmap#getxy.out --prefix=b "$bol" + ble/textmap#hit out $((x1%cols)) $((by+x1/cols)) "$bol" "$eol" # -> index + local nfill + if ((index==eol&&(nfill=x1-lx+(ly-by)*cols)>0)); then + ble/string#repeat ' ' "$nfill"; lpad=$lpad$ret + fi + else + index=$((bol+x1)) + if ((index>eol)); then + ble/string#repeat ' ' $((index-eol)); lpad=$lpad$ret + ((index=eol)) + fi + fi + ble/array#push ins_beg "$index" + ble/array#push ins_text "$lpad$ins" + done + local i=${#ins_beg[@]} + ble/keymap:vi/mark/start-edit-area + ble/keymap:vi/mark/commit-edit-area "$p1" "$p2" + while ((i--)); do + local index=${ins_beg[i]} text=${ins_text[i]} + ble/widget/.replace-range "$index" "$index" "$text" + done + ble/keymap:vi/mark/end-edit-area + local index + if ble/keymap:vi/mark/get-local-mark 60 && index=$ret; then + ble/widget/vi-command/goto-mark.impl "$index" + else + ble-edit/content/find-logical-bol; index=$ret + fi + ble-edit/content/eolp || ((index++)) + _ble_edit_ind=$index + return 0 +} +function ble/widget/vi_xmap/insert-mode { + local mark_type=${_ble_edit_mark_active%+} + if [[ $mark_type == vi_block ]]; then + local sub_ranges sub_x1 sub_x2 + ble/keymap:vi/extract-block '' '' first_line + ble/widget/vi_xmap/block-insert-mode.impl insert + else + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local beg=$_ble_edit_mark end=$_ble_edit_ind + ((beg<=end)) || local beg=$end end=$beg + if [[ $mark_type == vi_line ]]; then + local ret + ble-edit/content/find-logical-bol "$beg"; beg=$ret + fi + ble/widget/vi_xmap/cancel + _ble_edit_ind=$beg + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 + fi +} +function ble/widget/vi_xmap/append-mode { + local mark_type=${_ble_edit_mark_active%+} + if [[ $mark_type == vi_block ]]; then + local sub_ranges sub_x1 sub_x2 + ble/keymap:vi/extract-block '' '' first_line + ble/widget/vi_xmap/block-insert-mode.impl append + else + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + local beg=$_ble_edit_mark end=$_ble_edit_ind + ((beg<=end)) || local beg=$end end=$beg + if [[ $mark_type == vi_line ]]; then + if ((_ble_edit_mark>_ble_edit_ind)); then + local ret + ble-edit/content/find-logical-bol "$end"; end=$ret + fi + fi + ble-edit/content/eolp "$end" || ((end++)) + ble/widget/vi_xmap/cancel + _ble_edit_ind=$end + ble/widget/vi_nmap/.insert-mode "$ARG" + ble/keymap:vi/repeat/record + return 0 + fi +} +function ble/widget/vi_xmap/paste.impl { + local opts=$1 + [[ :$opts: != *:after:* ]]; local is_after=$? + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + [[ $REG ]] && ble/keymap:vi/register#load "$REG" + local mark_type=${_ble_edit_mark_active%+} + local kill_ring=$_ble_edit_kill_ring + local kill_type=$_ble_edit_kill_type + local adjustment= + if [[ $mark_type == vi_block ]]; then + if [[ $kill_type == L ]]; then + if ((is_after)); then + local ret; ble/keymap:vi/get-rectangle-height; local nline=$ret + adjustment=lastline:$nline + fi + elif [[ $kill_type == B:* ]]; then + is_after=0 + else + is_after=0 + if [[ $kill_ring != *$'\n'* ]]; then + ((${#kill_ring}>=2)) && adjustment=index:$((${#kill_ring}*ARG-1)) + local ret; ble/keymap:vi/get-rectangle-height; local nline=$ret + ble/string#repeat "$kill_ring"$'\n' "$nline"; kill_ring=${ret%$'\n'} + ble/string#repeat '0 ' "$nline"; kill_type=B:${ret% } + fi + fi + elif [[ $mark_type == vi_line ]]; then + if [[ $kill_type == L ]]; then + is_after=0 + elif [[ $kill_type == B:* ]]; then + is_after=0 kill_type=L kill_ring=$kill_ring$'\n' + else + is_after=0 kill_type=L + [[ $kill_ring == *$'\n' ]] && kill_ring=$kill_ring$'\n' + fi + else + is_after=0 + [[ $kill_type == L ]] && adjustment=newline + fi + ble/keymap:vi/mark/start-edit-area + local _ble_keymap_vi_mark_suppress_edit=1 + { + ble/widget/vi-command/operator d; local ext=$? # _ble_edit_kill_{ring,type} is set here + if [[ $adjustment == newline ]]; then + local -a KEYS=(10) + ble/widget/self-insert + elif [[ $adjustment == lastline:* ]]; then + local ret + ble-edit/content/find-logical-bol "$_ble_edit_ind" $((${adjustment#*:}-1)) + _ble_edit_ind=$ret + fi + local _ble_edit_kill_ring=$kill_ring + local _ble_edit_kill_type=$kill_type + ble/widget/vi_nmap/paste.impl "$ARG" '' "$is_after" + if [[ $adjustment == index:* ]]; then + local index=$((_ble_edit_ind+${adjustment#*:})) + ((index>${#_ble_edit_str}&&(index=${#_ble_edit_str}))) + ble/keymap:vi/needs-eol-fix "$index" && ((index--)) + _ble_edit_ind=$index + fi + } + ble/util/unlocal _ble_keymap_vi_mark_suppress_edit + ble/keymap:vi/mark/end-edit-area + ble/keymap:vi/repeat/record + return "$ext" +} +function ble/widget/vi_xmap/paste-after { + ble/widget/vi_xmap/paste.impl after +} +function ble/widget/vi_xmap/paste-before { + ble/widget/vi_xmap/paste.impl before +} +function ble/widget/vi_xmap/increment.impl { + local opts=$1 + local ARG FLAG REG; ble/keymap:vi/get-arg 1 + if [[ $FLAG ]]; then + ble/widget/.bell + return 1 + fi + local delta=$ARG + [[ :$opts: == *:decrease:* ]] && ((delta=-delta)) + local progress=0 + [[ :$opts: == *:progressive:* ]] && progress=$delta + local old_mark_active=$_ble_edit_mark_active # save + local mark_type=${_ble_edit_mark_active%+} + ble/widget/vi_xmap/.save-visual-state + ble/widget/vi_xmap/exit # Note: _ble_edit_mark_active will be cleared here + if [[ $mark_type == vi_block ]]; then + local sub_ranges sub_x1 sub_x2 + _ble_edit_mark_active=$old_mark_active ble/keymap:vi/extract-block + if ((${#sub_ranges[@]}==0)); then + ble/widget/.bell + return 1 + fi + else + local beg=$_ble_edit_mark end=$_ble_edit_ind + ((beg<=end)) || local beg=$end end=$beg + if [[ $mark_type == vi_line ]]; then + local ret + ble-edit/content/find-logical-bol "$beg"; local beg=$ret + ble-edit/content/find-logical-eol "$end"; local end=$ret + else + ble-edit/content/eolp "$end" || ((end++)) + fi + local -a lines + ble/string#split-lines lines "${_ble_edit_str:beg:end-beg}" + local line index=$beg + local -a sub_ranges + for line in "${lines[@]}"; do + [[ $line ]] && ble/array#push sub_ranges "$index:::::$line" + ((index+=${#line}+1)) + done + ((${#sub_ranges[@]})) || return 0 + fi + local sub rex_number='^([^0-9]*)([0-9]+)' shift=0 dmin=-1 dmax=-1 + for sub in "${sub_ranges[@]}"; do + local stext=${sub#*:*:*:*:*:} + [[ $stext =~ $rex_number ]] || continue + local rematch1=${BASH_REMATCH[1]} + local rematch2=${BASH_REMATCH[2]} + local offset=${#rematch1} length=${#rematch2} + local number=$((10#0$rematch2)) + [[ $rematch1 == *- ]] && ((number=-number,offset--,length++)) + ((number+=delta,delta+=progress)) + if [[ $rematch2 == 0?* ]]; then + local wsign=$((number<0?1:0)) + local zpad=$((wsign+${#rematch2}-${#number})) + if ((zpad>0)); then + local ret; ble/string#repeat 0 "$zpad" + number=${number::wsign}$ret${number:wsign} + fi + fi + local smin=${sub%%:*} + local beg=$((shift+smin+offset)) + local end=$((beg+length)) + ble/widget/.replace-range "$beg" "$end" "$number" + ((shift+=${#number}-length, + dmin<0&&(dmin=beg), + dmax=beg+${#number})) + done + local beg=${sub_ranges[0]%%:*} + ble/keymap:vi/needs-eol-fix "$beg" && ((beg--)) + _ble_edit_ind=$beg + ((dmin>=0)) && ble/keymap:vi/mark/set-previous-edit-area "$dmin" "$dmax" + ble/keymap:vi/repeat/record + return 0 +} +function ble/widget/vi_xmap/increment { ble/widget/vi_xmap/increment.impl increase; } +function ble/widget/vi_xmap/decrement { ble/widget/vi_xmap/increment.impl decrease; } +function ble/widget/vi_xmap/progressive-increment { ble/widget/vi_xmap/increment.impl progressive:increase; } +function ble/widget/vi_xmap/progressive-decrement { ble/widget/vi_xmap/increment.impl progressive:decrease; } +function ble-decode/keymap:vi_xmap/define { + ble/keymap:vi/set-up-command-map + ble-bind -f __default__ vi-command/decompose-meta + ble-bind -f 'ESC' vi_xmap/exit + ble-bind -f 'C-[' vi_xmap/exit + ble-bind -f 'C-c' vi_xmap/cancel + ble-bind -f '"' vi-command/register + ble-bind -f a vi-command/text-object + ble-bind -f i vi-command/text-object + ble-bind -f 'C-\ C-n' vi_xmap/cancel + ble-bind -f 'C-\ C-g' vi_xmap/cancel + ble-bind -f v vi_xmap/switch-to-charwise + ble-bind -f V vi_xmap/switch-to-linewise + ble-bind -f C-v vi_xmap/switch-to-blockwise + ble-bind -f C-q vi_xmap/switch-to-blockwise + ble-bind -f 'g v' vi-command/previous-visual-area + ble-bind -f C-g vi_xmap/switch-to-select + ble-bind -f o vi_xmap/exchange-points + ble-bind -f O vi_xmap/exchange-boundaries + ble-bind -f '~' 'vi-command/operator toggle_case' + ble-bind -f 'u' 'vi-command/operator u' + ble-bind -f 'U' 'vi-command/operator U' + ble-bind -f 's' 'vi-command/operator c' + ble-bind -f 'x' 'vi-command/operator d' + ble-bind -f delete 'vi-command/operator d' + ble-bind -f r vi_xmap/visual-replace-char + ble-bind -f C vi_xmap/replace-block-lines + ble-bind -f D vi_xmap/delete-block-lines + ble-bind -f X vi_xmap/delete-block-lines + ble-bind -f S vi_xmap/delete-lines + ble-bind -f R vi_xmap/delete-lines + ble-bind -f Y vi_xmap/copy-block-or-lines + ble-bind -f J vi_xmap/connect-line-with-space + ble-bind -f 'g J' vi_xmap/connect-line + ble-bind -f I vi_xmap/insert-mode + ble-bind -f A vi_xmap/append-mode + ble-bind -f p vi_xmap/paste-after + ble-bind -f P vi_xmap/paste-before + ble-bind -f 'C-a' vi_xmap/increment + ble-bind -f 'C-x' vi_xmap/decrement + ble-bind -f 'g C-a' vi_xmap/progressive-increment + ble-bind -f 'g C-x' vi_xmap/progressive-decrement + ble-bind -f f1 vi_xmap/command-help + ble-bind -f K vi_xmap/command-help +} +function ble-decode/keymap:vi_smap/define { + ble-bind -f __default__ vi-command/decompose-meta + ble-bind -f 'ESC' vi_xmap/exit + ble-bind -f 'C-[' vi_xmap/exit + ble-bind -f 'C-c' vi_xmap/cancel + ble-bind -f 'C-\ C-n' nop + ble-bind -f 'C-\ C-n' vi_xmap/cancel + ble-bind -f 'C-\ C-g' vi_xmap/cancel + ble-bind -f C-v vi_xmap/switch-to-visual-blockwise + ble-bind -f C-q vi_xmap/switch-to-visual-blockwise + ble-bind -f C-g vi_xmap/switch-to-visual + ble-bind -f delete 'vi-command/operator d' + ble-bind -f 'C-?' 'vi-command/operator d' + ble-bind -f 'DEL' 'vi-command/operator d' + ble-bind -f 'C-h' 'vi-command/operator d' + ble-bind -f 'BS' 'vi-command/operator d' + ble-bind -f __defchar__ vi_smap/self-insert + ble-bind -f paste_begin vi-command/bracketed-paste + ble-bind -f 'C-a' vi_xmap/increment + ble-bind -f 'C-x' vi_xmap/decrement + ble-bind -f f1 vi_xmap/command-help + ble-bind -c 'C-z' fg + ble-bind -f home 'vi_smap/@nomarked vi-command/beginning-of-line' + ble-bind -f end 'vi_smap/@nomarked vi-command/forward-eol' + ble-bind -f C-m 'vi_smap/@nomarked vi-command/forward-first-non-space' + ble-bind -f RET 'vi_smap/@nomarked vi-command/forward-first-non-space' + ble-bind -f S-home 'vi-command/beginning-of-line' + ble-bind -f S-end 'vi-command/forward-eol' + ble-bind -f S-C-m 'vi-command/forward-first-non-space' + ble-bind -f S-RET 'vi-command/forward-first-non-space' + ble-bind -f C-right 'vi_smap/@nomarked vi-command/forward-vword' + ble-bind -f C-left 'vi_smap/@nomarked vi-command/backward-vword' + ble-bind -f S-C-right 'vi-command/forward-vword' + ble-bind -f S-C-left 'vi-command/backward-vword' + ble-bind -f left 'vi_smap/@nomarked vi-command/backward-char' + ble-bind -f right 'vi_smap/@nomarked vi-command/forward-char' + ble-bind -f 'C-?' 'vi_smap/@nomarked vi-command/backward-char wrap' + ble-bind -f 'DEL' 'vi_smap/@nomarked vi-command/backward-char wrap' + ble-bind -f 'C-h' 'vi_smap/@nomarked vi-command/backward-char wrap' + ble-bind -f 'BS' 'vi_smap/@nomarked vi-command/backward-char wrap' + ble-bind -f SP 'vi_smap/@nomarked vi-command/forward-char wrap' + ble-bind -f S-left 'vi-command/backward-char' + ble-bind -f S-right 'vi-command/forward-char' + ble-bind -f 'S-C-?' 'vi-command/backward-char wrap' + ble-bind -f 'S-DEL' 'vi-command/backward-char wrap' + ble-bind -f 'S-C-h' 'vi-command/backward-char wrap' + ble-bind -f 'S-BS' 'vi-command/backward-char wrap' + ble-bind -f S-SP 'vi-command/forward-char wrap' + ble-bind -f down 'vi_smap/@nomarked vi-command/forward-line' + ble-bind -f C-n 'vi_smap/@nomarked vi-command/forward-line' + ble-bind -f C-j 'vi_smap/@nomarked vi-command/forward-line' + ble-bind -f up 'vi_smap/@nomarked vi-command/backward-line' + ble-bind -f C-p 'vi_smap/@nomarked vi-command/backward-line' + ble-bind -f C-home 'vi_smap/@nomarked vi-command/first-nol' + ble-bind -f C-end 'vi_smap/@nomarked vi-command/last-eol' + ble-bind -f S-down 'vi-command/forward-line' + ble-bind -f S-C-n 'vi-command/forward-line' + ble-bind -f S-C-j 'vi-command/forward-line' + ble-bind -f S-up 'vi-command/backward-line' + ble-bind -f S-C-p 'vi-command/backward-line' + ble-bind -f S-C-home 'vi-command/first-nol' + ble-bind -f S-C-end 'vi-command/last-eol' +} +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 + ble/widget/accept-line + else + ble/widget/"$@" + fi +} +function ble/widget/vi_imap/delete-region-or { + if [[ $_ble_edit_mark_active ]]; then + ble/keymap:vi/imap-repeat/reset + if ((_ble_edit_ind!=_ble_edit_mark)); then + ble/keymap:vi/undo/add more + ble/widget/delete-region + ble/keymap:vi/undo/add more + fi + else + ble/widget/"$@" + fi +} +function ble/widget/vi_imap/overwrite-mode { + ble-edit/content/clear-arg + if [[ $_ble_edit_overwrite_mode ]]; then + _ble_edit_overwrite_mode= + else + _ble_edit_overwrite_mode=${_ble_keymap_vi_insert_overwrite:-R} + fi + ble/keymap:vi/update-mode-name + return 0 +} +function ble/widget/vi_imap/delete-backward-word { + local space=$' \t' nl=$'\n' + local rex="($_ble_keymap_vi_REX_WORD)[$space]*\$|[$space]+\$|$nl\$" + if [[ ${_ble_edit_str::_ble_edit_ind} =~ $rex ]]; then + local index=$((_ble_edit_ind-${#BASH_REMATCH})) + if ((index!=_ble_edit_ind)); then + ble/keymap:vi/undo/add more + ble/widget/.delete-range "$index" "$_ble_edit_ind" + ble/keymap:vi/undo/add more + fi + return 0 + else + ble/widget/.bell + return 1 + fi +} +function ble/widget/vi_imap/quoted-insert-char { + ble/keymap:vi/imap-repeat/pop + _ble_edit_mark_active= + _ble_decode_char__hook=ble/widget/vi_imap/quoted-insert-char.hook + return 147 +} +function ble/widget/vi_imap/quoted-insert-char.hook { + ble/keymap:vi/imap/invoke-widget ble/widget/self-insert "$1" +} +function ble/widget/vi_imap/quoted-insert { + ble/keymap:vi/imap-repeat/pop + _ble_edit_mark_active= + _ble_decode_key__hook=ble/widget/vi_imap/quoted-insert.hook + return 147 +} +function ble/widget/vi_imap/quoted-insert.hook { + ble/keymap:vi/imap/invoke-widget ble/widget/quoted-insert.hook "$1" +} +function ble/widget/vi_imap/bracketed-paste { + ble/keymap:vi/imap-repeat/pop + ble/widget/bracketed-paste + _ble_edit_bracketed_paste_proc=ble/widget/vi_imap/bracketed-paste.proc + return 147 +} +function ble/widget/vi_imap/bracketed-paste.proc { + local WIDGET=ble/widget/batch-insert + local -a KEYS; KEYS=("$@") + ble/keymap:vi/imap-repeat/push + builtin eval -- "$WIDGET" +} +_ble_keymap_vi_brackated_paste_mark_active= +function ble/widget/vi-command/bracketed-paste { + local ARG FLAG REG; ble/keymap:vi/get-arg 1 # discard args + _ble_keymap_vi_brackated_paste_mark_active=$_ble_edit_mark_active + _ble_edit_mark_active= + ble/widget/bracketed-paste + _ble_edit_bracketed_paste_proc=ble/widget/vi-command/bracketed-paste.proc + return 147 +} +function ble/widget/vi-command/bracketed-paste.proc { + if [[ $_ble_decode_keymap == vi_nmap ]]; then + local isbol index=$_ble_edit_ind + ble-edit/content/bolp && isbol=1 + ble/decode/widget/call-interactively 'ble/widget/vi_nmap/append-mode' 97 + [[ $isbol ]] && ((_ble_edit_ind=index)) # 行頭にいたときは戻る + ble/widget/vi_imap/bracketed-paste.proc "$@" + ble/keymap:vi/imap/invoke-widget \ + ble/widget/vi_imap/normal-mode $((_ble_decode_Ctrl|0x5b)) + elif [[ $_ble_decode_keymap == vi_[xs]map ]]; then + local _ble_edit_mark_active=$_ble_keymap_vi_brackated_paste_mark_active + ble/decode/widget/call-interactively 'ble/widget/vi-command/operator c' 99 || return 1 + ble/widget/vi_imap/bracketed-paste.proc "$@" + ble/keymap:vi/imap/invoke-widget \ + ble/widget/vi_imap/normal-mode $((_ble_decode_Ctrl|0x5b)) + elif [[ $_ble_decode_keymap == vi_omap ]]; then + ble/widget/vi_omap/cancel + ble/widget/.bell + return 1 + else # vi_omap + ble/widget/.bell + return 1 + fi +} +function ble/widget/vi_imap/insert-digraph.hook { + local -a KEYS; KEYS=("$1") + ble/widget/self-insert +} +function ble/widget/vi_imap/insert-digraph { + ble/decode/keymap/push vi_digraph + _ble_keymap_vi_digraph__hook=ble/widget/vi_imap/insert-digraph.hook + return 0 +} +function ble/widget/vi_imap/newline { + local ret + ble-edit/content/find-logical-bol; local bol=$ret + ble-edit/content/find-non-space "$bol"; local nol=$ret + ble/widget/default/newline + ((bol<nol)) && ble/widget/.insert-string "${_ble_edit_str:bol:nol-bol}" + return 0 +} +function ble/widget/vi_imap/delete-backward-indent-or { + local rex=$'(^|\n)([ \t]+)$' + if [[ ${_ble_edit_str::_ble_edit_ind} =~ $rex ]]; then + local rematch2=${BASH_REMATCH[2]} # Note: for bash-3.1 ${#arr[n]} bug + if [[ $rematch2 ]]; then + ble/keymap:vi/undo/add more + ble/widget/.delete-range $((_ble_edit_ind-${#rematch2})) "$_ble_edit_ind" + ble/keymap:vi/undo/add more + fi + return 0 + else + ble/widget/"$@" + fi +} +function ble-decode/keymap:vi_imap/define { + local ble_bind_nometa=1 + ble-decode/keymap:safe/bind-common + ble-decode/keymap:safe/bind-history + ble-bind -f 'C-d' 'delete-region-or delete-forward-char-or-exit' + ble-bind -f 'SP' 'magic-space' + ble-bind -f 'C-j' 'accept-line' + ble-bind -f 'C-RET' 'accept-line' + ble-bind -f 'C-m' 'accept-single-line-or-newline' + ble-bind -f 'RET' 'accept-single-line-or-newline' + ble-bind -f 'C-x C-e' 'edit-and-execute-command' + ble-bind -f 'C-g' 'bell' + ble-bind -f 'C-x C-g' 'bell' + ble-bind -f 'C-l' 'clear-screen' + ble-bind -f 'f1' 'command-help' + ble-bind -f 'C-x C-v' 'display-shell-version' + ble-bind -c 'C-z' 'fg' + ble-bind -f insert 'vi_imap/overwrite-mode' + ble-bind -f 'C-q' 'vi_imap/quoted-insert' + ble-bind -f 'C-v' 'vi_imap/quoted-insert' + ble-bind -f 'C-RET' 'newline' + ble-bind -f paste_begin 'vi_imap/bracketed-paste' + ble-bind -f 'C-?' 'vi_imap/delete-region-or vi_imap/delete-backward-indent-or delete-backward-char' + ble-bind -f 'DEL' 'vi_imap/delete-region-or vi_imap/delete-backward-indent-or delete-backward-char' + ble-bind -f 'C-h' 'vi_imap/delete-region-or vi_imap/delete-backward-indent-or delete-backward-char' + ble-bind -f 'BS' 'vi_imap/delete-region-or vi_imap/delete-backward-indent-or delete-backward-char' + ble-bind -f 'C-w' 'vi_imap/delete-backward-word' + ble-decode/keymap:vi_imap/bind-complete + ble-bind -f 'C-\' bell + ble-bind -f 'C-^' bell + 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__ + ble-bind -f 'ESC' 'vi_imap/normal-mode' + ble-bind -f 'C-[' 'vi_imap/normal-mode' + ble-bind -f 'C-c' 'vi_imap/normal-mode-without-insert-leave' + ble-bind -f 'C-o' 'vi_imap/single-command-mode' +} +function ble-decode/keymap:vi_imap/define-meta-bindings { + local ble_bind_keymap=vi_imap + ble-bind -f 'M-^' 'history-expand-line' + ble-bind -f 'C-M-l' 'redraw-line' + ble-bind -f 'M-#' 'insert-comment' + ble-bind -f 'M-C-e' 'shell-expand-line' + ble-bind -f 'M-&' 'tilde-expand' + ble-bind -f 'C-M-g' 'bell' + ble-bind -c 'M-z' 'fg' + ble-bind -f 'M-C-m' 'newline' + ble-bind -f 'M-RET' 'newline' + ble-bind -f 'M-SP' 'set-mark' + ble-bind -f 'M-w' 'copy-region-or copy-uword' + ble-bind -f 'M-y' 'yank-pop' + ble-bind -f 'M-S-y' 'yank-pop backward' + ble-bind -f 'M-Y' 'yank-pop backward' + ble-bind -f 'M-\' 'delete-horizontal-space' + ble-bind -f 'M-right' '@nomarked forward-sword' + ble-bind -f 'M-left' '@nomarked backward-sword' + ble-bind -f 'S-M-right' '@marked forward-sword' + ble-bind -f 'S-M-left' '@marked backward-sword' + ble-bind -f 'M-d' 'kill-forward-cword' + ble-bind -f 'M-h' 'kill-backward-cword' + ble-bind -f 'M-delete' 'copy-forward-sword' + ble-bind -f 'M-C-?' 'copy-backward-sword' + ble-bind -f 'M-DEL' 'copy-backward-sword' + ble-bind -f 'M-C-h' 'copy-backward-sword' + ble-bind -f 'M-BS' 'copy-backward-sword' + ble-bind -f 'M-f' '@nomarked forward-cword' + ble-bind -f 'M-b' '@nomarked backward-cword' + ble-bind -f 'M-F' '@marked forward-cword' + ble-bind -f 'M-B' '@marked backward-cword' + ble-bind -f 'M-S-f' '@marked forward-cword' + ble-bind -f 'M-S-b' '@marked backward-cword' + ble-bind -f 'M-c' 'capitalize-eword' + ble-bind -f 'M-l' 'downcase-eword' + ble-bind -f 'M-u' 'upcase-eword' + ble-bind -f 'M-t' 'transpose-ewords' + ble-bind -f 'M-m' '@nomarked non-space-beginning-of-line' + ble-bind -f 'S-M-m' '@marked non-space-beginning-of-line' + ble-bind -f 'M-M' '@marked non-space-beginning-of-line' + ble-bind -f 'M-<' 'history-beginning' + ble-bind -f 'M->' 'history-end' + ble-bind -f 'M-.' 'insert-last-argument' + ble-bind -f 'M-_' 'insert-last-argument' + ble-bind -f 'M-C-y' 'insert-nth-argument' + ble-bind -f 'M-?' 'complete show_menu' + ble-bind -f 'M-*' 'complete insert_all' + ble-bind -f 'M-{' 'complete insert_braces' + ble-bind -f 'M-/' 'complete context=filename' + ble-bind -f 'M-~' 'complete context=username' + ble-bind -f 'M-$' 'complete context=variable' + ble-bind -f 'M-@' 'complete context=hostname' + ble-bind -f 'M-!' 'complete context=command' + ble-bind -f "M-'" 'sabbrev-expand' + ble-bind -f 'M-g' 'complete context=glob' + ble-bind -f 'M-C-i' 'complete context=dynamic-history' + ble-bind -f 'M-TAB' 'complete context=dynamic-history' +} +_ble_keymap_vi_cmap_hook= +_ble_keymap_vi_cmap_cancel_hook= +_ble_keymap_vi_cmap_before_command= +_ble_keymap_vi_cmap_history=() +_ble_keymap_vi_cmap_history_edit=() +_ble_keymap_vi_cmap_history_dirt=() +_ble_keymap_vi_cmap_history_index=0 +function ble/keymap:vi/async-commandline-mode { + local hook=$1 + _ble_keymap_vi_cmap_hook=$hook + _ble_keymap_vi_cmap_cancel_hook= + _ble_keymap_vi_cmap_before_command= + ble/textarea#render + ble/textarea#save-state _ble_keymap_vi_cmap + ble/util/save-vars _ble_keymap_vi_cmap _ble_canvas_panel_focus + _ble_keymap_vi_cmap_history_prefix=$_ble_history_prefix + ble/decode/keymap/push vi_cmap + ble/keymap:vi/update-mode-name + _ble_textarea_panel=1 + _ble_canvas_panel_focus=1 + ble/textarea#invalidate + _ble_edit_PS1=$PS2 + _ble_prompt_ps1_data=(0 '' '' 0 0 0 32 0 '' '') + _ble_edit_dirty_observer=() + ble/widget/.newline/clear-content + _ble_edit_arg= + ble-edit/undo/clear-all + ble/history/set-prefix _ble_keymap_vi_cmap + _ble_syntax_lang=text + _ble_highlight_layer__list=(plain region overwrite_mode) +} +function ble/widget/vi_cmap/accept { + local hook=${_ble_keymap_vi_cmap_hook} + _ble_keymap_vi_cmap_hook= + local result=$_ble_edit_str + [[ $result ]] && ble/history/add "$result" # Note: cancel でも登録する + local -a DRAW_BUFF=() + ble/canvas/panel#set-height.draw "$_ble_textarea_panel" 0 + ble/canvas/bflush.draw + ble/textarea#restore-state _ble_keymap_vi_cmap + ble/textarea#clear-state _ble_keymap_vi_cmap + ble/util/restore-vars _ble_keymap_vi_cmap _ble_canvas_panel_focus + [[ $_ble_edit_overwrite_mode ]] && ble/util/buffer "$_ble_term_civis" + ble/history/set-prefix "$_ble_keymap_vi_cmap_history_prefix" + ble/decode/keymap/pop + ble/keymap:vi/update-mode-name + if [[ $hook ]]; then + builtin eval -- "$hook \"\$result\"" + else + ble/keymap:vi/adjust-command-mode + return 0 + fi +} +function ble/widget/vi_cmap/cancel { + _ble_keymap_vi_cmap_hook=$_ble_keymap_vi_cmap_cancel_hook + ble/widget/vi_cmap/accept +} +function ble/widget/vi_cmap/__before_widget__ { + if [[ $_ble_keymap_vi_cmap_before_command ]]; then + builtin eval -- "$_ble_keymap_vi_cmap_before_command" + fi +} +function ble/widget/vi_cmap/__line_limit__.edit { + local content=$1 + ble/widget/edit-and-execute-command.edit "$content" no-newline; local ext=$? + ((ext==127)) && return "$ext" + ble-edit/content/reset "$ret" + ble/widget/vi_cmap/accept +} +function ble/widget/vi_cmap/__line_limit__ { + ble/widget/__line_limit__ vi_cmap/__line_limit__.edit +} +function ble-decode/keymap:vi_cmap/define { + local ble_bind_nometa= + ble-decode/keymap:safe/bind-common + ble-decode/keymap:safe/bind-history + ble-decode/keymap:safe/bind-complete + ble-bind -f __before_widget__ vi_cmap/__before_widget__ + ble-bind -f __line_limit__ vi_cmap/__line_limit__ + ble-bind -f 'ESC' vi_cmap/cancel + ble-bind -f 'C-[' vi_cmap/cancel + ble-bind -f 'C-c' vi_cmap/cancel + ble-bind -f 'C-m' vi_cmap/accept + ble-bind -f 'RET' vi_cmap/accept + ble-bind -f 'C-j' vi_cmap/accept + ble-bind -f 'C-g' bell + ble-bind -f 'C-x C-g' bell + ble-bind -f 'C-M-g' bell + ble-bind -f 'C-l' redraw-line + ble-bind -f 'C-M-l' redraw-line + ble-bind -f 'C-x C-v' display-shell-version + ble-bind -f 'C-\' bell + ble-bind -f 'C-^' bell +} +function ble-decode/keymap:vi/initialize { + local fname_keymap_cache=$_ble_base_cache/keymap.vi + if [[ -s $fname_keymap_cache && + $fname_keymap_cache -nt $_ble_base/keymap/vi.sh && + $fname_keymap_cache -nt $_ble_base/lib/init-cmap.sh ]]; then + source "$fname_keymap_cache" && return 0 + fi + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi..." + { + ble/decode/keymap#load isearch dump + ble/decode/keymap#load nsearch dump + ble/decode/keymap#load vi_imap dump + ble/decode/keymap#load vi_nmap dump + ble/decode/keymap#load vi_omap dump + ble/decode/keymap#load vi_xmap dump + ble/decode/keymap#load vi_cmap dump + } 3>| "$fname_keymap_cache" + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi... done" +} +ble-decode/keymap:vi/initialize +blehook/invoke keymap_load +blehook/invoke keymap_vi_load +return 0 diff --git a/.local/src/blesh/keymap/vi_digraph.sh b/.local/src/blesh/keymap/vi_digraph.sh new file mode 100644 index 0000000..dce0bf4 --- /dev/null +++ b/.local/src/blesh/keymap/vi_digraph.sh @@ -0,0 +1,51 @@ +# this script is a part of blesh (https://github.com/akinomyoga/ble.sh) under BSD-3-Clause license +_ble_keymap_vi_digraph__hook= +function ble/widget/vi_digraph/.proc { + local code=$1 + local hook=${_ble_keymap_vi_digraph__hook:-ble-decode-key} + _ble_keymap_vi_digraph__hook= + ble/decode/keymap/pop + builtin eval -- "$hook $code" +} +function ble/widget/vi_digraph/defchar { + ble/widget/vi_digraph/.proc "${KEYS[0]}" +} +function ble/widget/vi_digraph/default { + local key=${KEYS[0]} + local flag=$((key&_ble_decode_MaskFlag)) char=$((key&_ble_decode_MaskChar)) + if ((flag==_ble_decode_Ctrl&&63<=char&&char<128&&(char&0x1F)!=0)); then + ((char=char==63?127:char&0x1F)) + ble/widget/vi_digraph/.proc "$char" + return 0 + fi + ble/widget/.bell + return 0 +} +function ble-decode/keymap:vi_digraph/define { + ble-bind -f __defchar__ vi_digraph/defchar + ble-bind -f __default__ vi_digraph/default + ble-bind -f __line_limit__ nop + local lines; ble/util/mapfile lines < "$_ble_base/keymap/vi_digraph.txt" + local line field ch1 ch2 code + for line in "${lines[@]}"; do + [[ $line == ??' '* ]] || continue + ch1=${line::1} + ch2=${line:1:1} + code=${line:3} + ble-bind -f "$ch1 $ch2" "vi_digraph/.proc $code" + done +} +function ble-decode/keymap:vi_digraph/initialize { + local fname_keymap_cache=$_ble_base_cache/keymap.vi_digraph + if [[ -s $fname_keymap_cache && + $fname_keymap_cache -nt $_ble_base/keymap/vi_digraph.sh && + $fname_keymap_cache -nt $_ble_base/keymap/vi_digraph.txt ]]; then + source "$fname_keymap_cache" + return 0 + fi + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi_digraph..." + : >| "$fname_keymap_cache" + ble/decode/keymap#load vi_digraph dump 3>> "$fname_keymap_cache" + ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.vi_digraph... done" +} +ble-decode/keymap:vi_digraph/initialize diff --git a/.local/src/blesh/keymap/vi_digraph.txt b/.local/src/blesh/keymap/vi_digraph.txt new file mode 100644 index 0000000..9086f91 --- /dev/null +++ b/.local/src/blesh/keymap/vi_digraph.txt @@ -0,0 +1,1304 @@ +NU 0 +SH 1 +SX 2 +EX 3 +ET 4 +EQ 5 +AK 6 +BL 7 +BS 8 +HT 9 +LF 10 +VT 11 +FF 12 +CR 13 +SO 14 +SI 15 +DL 16 +D1 17 +D2 18 +D3 19 +D4 20 +NK 21 +SY 22 +EB 23 +CN 24 +EM 25 +SB 26 +EC 27 +FS 28 +GS 29 +RS 30 +US 31 +SP 32 +Nb 35 +DO 36 +At 64 +<( 91 +// 92 +)> 93 +'> 94 +'! 96 +(! 123 +!! 124 +!) 125 +'? 126 +DT 127 +PA 128 +HO 129 +BH 130 +NH 131 +IN 132 +NL 133 +SA 134 +ES 135 +HS 136 +HJ 137 +VS 138 +PD 139 +PU 140 +RI 141 +S2 142 +S3 143 +DC 144 +P1 145 +P2 146 +TS 147 +CC 148 +MW 149 +SG 150 +EG 151 +SS 152 +GC 153 +SC 154 +CI 155 +ST 156 +OC 157 +PM 158 +AC 159 +NS 160 +!I 161 +Ct 162 +Pd 163 +Cu 164 +Ye 165 +BB 166 +SE 167 +': 168 +Co 169 +-a 170 +<< 171 +NO 172 +-- 173 +Rg 174 +'m 175 +DG 176 ++- 177 +2S 178 +3S 179 +'' 180 +My 181 +PI 182 +.M 183 +', 184 +1S 185 +-o 186 +>> 187 +14 188 +12 189 +34 190 +?I 191 +A! 192 +A' 193 +A> 194 +A? 195 +A: 196 +AA 197 +AE 198 +C, 199 +E! 200 +E' 201 +E> 202 +E: 203 +I! 204 +I' 205 +I> 206 +I: 207 +D- 208 +N? 209 +O! 210 +O' 211 +O> 212 +O? 213 +O: 214 +*X 215 +O/ 216 +U! 217 +U' 218 +U> 219 +U: 220 +Y' 221 +TH 222 +ss 223 +a! 224 +a' 225 +a> 226 +a? 227 +a: 228 +aa 229 +ae 230 +c, 231 +e! 232 +e' 233 +e> 234 +e: 235 +i! 236 +i' 237 +i> 238 +i: 239 +d- 240 +n? 241 +o! 242 +o' 243 +o> 244 +o? 245 +o: 246 +-: 247 +o/ 248 +u! 249 +u' 250 +u> 251 +u: 252 +y' 253 +th 254 +y: 255 +A- 256 +a- 257 +A( 258 +a( 259 +A; 260 +a; 261 +C' 262 +c' 263 +C> 264 +c> 265 +C. 266 +c. 267 +C< 268 +c< 269 +D< 270 +d< 271 +D/ 272 +d/ 273 +E- 274 +e- 275 +E( 276 +e( 277 +E. 278 +e. 279 +E; 280 +e; 281 +E< 282 +e< 283 +G> 284 +g> 285 +G( 286 +g( 287 +G. 288 +g. 289 +G, 290 +g, 291 +H> 292 +h> 293 +H/ 294 +h/ 295 +I? 296 +i? 297 +I- 298 +i- 299 +I( 300 +i( 301 +I; 302 +i; 303 +I. 304 +i. 305 +IJ 306 +ij 307 +J> 308 +j> 309 +K, 310 +k, 311 +kk 312 +L' 313 +l' 314 +L, 315 +l, 316 +L< 317 +l< 318 +L. 319 +l. 320 +L/ 321 +l/ 322 +N' 323 +n' 324 +N, 325 +n, 326 +N< 327 +n< 328 +'n 329 +NG 330 +ng 331 +O- 332 +o- 333 +O( 334 +o( 335 +O" 336 +o" 337 +OE 338 +oe 339 +R' 340 +r' 341 +R, 342 +r, 343 +R< 344 +r< 345 +S' 346 +s' 347 +S> 348 +s> 349 +S, 350 +s, 351 +S< 352 +s< 353 +T, 354 +t, 355 +T< 356 +t< 357 +T/ 358 +t/ 359 +U? 360 +u? 361 +U- 362 +u- 363 +U( 364 +u( 365 +U0 366 +u0 367 +U" 368 +u" 369 +U; 370 +u; 371 +W> 372 +w> 373 +Y> 374 +y> 375 +Y: 376 +Z' 377 +z' 378 +Z. 379 +z. 380 +Z< 381 +z< 382 +O9 416 +o9 417 +OI 418 +oi 419 +yr 422 +U9 431 +u9 432 +Z/ 437 +z/ 438 +ED 439 +A< 461 +a< 462 +I< 463 +i< 464 +O< 465 +o< 466 +U< 467 +u< 468 +A1 478 +a1 479 +A7 480 +a7 481 +A3 482 +a3 483 +G/ 484 +g/ 485 +G< 486 +g< 487 +K< 488 +k< 489 +O; 490 +o; 491 +O1 492 +o1 493 +EZ 494 +ez 495 +j< 496 +G' 500 +g' 501 +;S 703 +'< 711 +'( 728 +'. 729 +'0 730 +'; 731 +'" 733 +A% 902 +E% 904 +Y% 905 +I% 906 +O% 908 +U% 910 +W% 911 +i3 912 +A* 913 +B* 914 +G* 915 +D* 916 +E* 917 +Z* 918 +Y* 919 +H* 920 +I* 921 +K* 922 +L* 923 +M* 924 +N* 925 +C* 926 +O* 927 +P* 928 +R* 929 +S* 931 +T* 932 +U* 933 +F* 934 +X* 935 +Q* 936 +W* 937 +J* 938 +V* 939 +a% 940 +e% 941 +y% 942 +i% 943 +u3 944 +a* 945 +b* 946 +g* 947 +d* 948 +e* 949 +z* 950 +y* 951 +h* 952 +i* 953 +k* 954 +l* 955 +m* 956 +n* 957 +c* 958 +o* 959 +p* 960 +r* 961 +*s 962 +s* 963 +t* 964 +u* 965 +f* 966 +x* 967 +q* 968 +w* 969 +j* 970 +v* 971 +o% 972 +u% 973 +w% 974 +'G 984 +,G 985 +T3 986 +t3 987 +M3 988 +m3 989 +K3 990 +k3 991 +P3 992 +p3 993 +'% 1012 +j3 1013 +IO 1025 +D% 1026 +G% 1027 +IE 1028 +DS 1029 +II 1030 +YI 1031 +J% 1032 +LJ 1033 +NJ 1034 +Ts 1035 +KJ 1036 +V% 1038 +DZ 1039 +A= 1040 +B= 1041 +V= 1042 +G= 1043 +D= 1044 +E= 1045 +Z% 1046 +Z= 1047 +I= 1048 +J= 1049 +K= 1050 +L= 1051 +M= 1052 +N= 1053 +O= 1054 +P= 1055 +R= 1056 +S= 1057 +T= 1058 +U= 1059 +F= 1060 +H= 1061 +C= 1062 +C% 1063 +S% 1064 +Sc 1065 +=" 1066 +Y= 1067 +%" 1068 +JE 1069 +JU 1070 +JA 1071 +a= 1072 +b= 1073 +v= 1074 +g= 1075 +d= 1076 +e= 1077 +z% 1078 +z= 1079 +i= 1080 +j= 1081 +k= 1082 +l= 1083 +m= 1084 +n= 1085 +o= 1086 +p= 1087 +r= 1088 +s= 1089 +t= 1090 +u= 1091 +f= 1092 +h= 1093 +c= 1094 +c% 1095 +s% 1096 +sc 1097 +=' 1098 +y= 1099 +%' 1100 +je 1101 +ju 1102 +ja 1103 +io 1105 +d% 1106 +g% 1107 +ie 1108 +ds 1109 +ii 1110 +yi 1111 +j% 1112 +lj 1113 +nj 1114 +ts 1115 +kj 1116 +v% 1118 +dz 1119 +Y3 1122 +y3 1123 +O3 1130 +o3 1131 +F3 1138 +f3 1139 +V3 1140 +v3 1141 +C3 1152 +c3 1153 +G3 1168 +g3 1169 +A+ 1488 +B+ 1489 +G+ 1490 +D+ 1491 +H+ 1492 +W+ 1493 +Z+ 1494 +X+ 1495 +Tj 1496 +J+ 1497 +K% 1498 +K+ 1499 +L+ 1500 +M% 1501 +M+ 1502 +N% 1503 +N+ 1504 +S+ 1505 +E+ 1506 +P% 1507 +P+ 1508 +Zj 1509 +ZJ 1510 +Q+ 1511 +R+ 1512 +Sh 1513 +T+ 1514 +,+ 1548 +;+ 1563 +?+ 1567 +H' 1569 +aM 1570 +aH 1571 +wH 1572 +ah 1573 +yH 1574 +a+ 1575 +b+ 1576 +tm 1577 +t+ 1578 +tk 1579 +g+ 1580 +hk 1581 +x+ 1582 +d+ 1583 +dk 1584 +r+ 1585 +z+ 1586 +s+ 1587 +sn 1588 +c+ 1589 +dd 1590 +tj 1591 +zH 1592 +e+ 1593 +i+ 1594 +++ 1600 +f+ 1601 +q+ 1602 +k+ 1603 +l+ 1604 +m+ 1605 +n+ 1606 +h+ 1607 +w+ 1608 +j+ 1609 +y+ 1610 +:+ 1611 +"+ 1612 +=+ 1613 +/+ 1614 +'+ 1615 +1+ 1616 +3+ 1617 +0+ 1618 +aS 1648 +p+ 1662 +v+ 1700 +gf 1711 +0a 1776 +1a 1777 +2a 1778 +3a 1779 +4a 1780 +5a 1781 +6a 1782 +7a 1783 +8a 1784 +9a 1785 +B. 7682 +b. 7683 +B_ 7686 +b_ 7687 +D. 7690 +d. 7691 +D_ 7694 +d_ 7695 +D, 7696 +d, 7697 +F. 7710 +f. 7711 +G- 7712 +g- 7713 +H. 7714 +h. 7715 +H: 7718 +h: 7719 +H, 7720 +h, 7721 +K' 7728 +k' 7729 +K_ 7732 +k_ 7733 +L_ 7738 +l_ 7739 +M' 7742 +m' 7743 +M. 7744 +m. 7745 +N. 7748 +n. 7749 +N_ 7752 +n_ 7753 +P' 7764 +p' 7765 +P. 7766 +p. 7767 +R. 7768 +r. 7769 +R_ 7774 +r_ 7775 +S. 7776 +s. 7777 +T. 7786 +t. 7787 +T_ 7790 +t_ 7791 +V? 7804 +v? 7805 +W! 7808 +w! 7809 +W' 7810 +w' 7811 +W: 7812 +w: 7813 +W. 7814 +w. 7815 +X. 7818 +x. 7819 +X: 7820 +x: 7821 +Y. 7822 +y. 7823 +Z> 7824 +z> 7825 +Z_ 7828 +z_ 7829 +h_ 7830 +t: 7831 +w0 7832 +y0 7833 +A2 7842 +a2 7843 +E2 7866 +e2 7867 +E? 7868 +e? 7869 +I2 7880 +i2 7881 +O2 7886 +o2 7887 +U2 7910 +u2 7911 +Y! 7922 +y! 7923 +Y2 7926 +y2 7927 +Y? 7928 +y? 7929 +;' 7936 +,' 7937 +;! 7938 +,! 7939 +?; 7940 +?, 7941 +!: 7942 +?: 7943 +1N 8194 +1M 8195 +3M 8196 +4M 8197 +6M 8198 +1T 8201 +1H 8202 +-1 8208 +-N 8211 +-M 8212 +-3 8213 +!2 8214 +=2 8215 +'6 8216 +'9 8217 +.9 8218 +9' 8219 +"6 8220 +"9 8221 +:9 8222 +9" 8223 +/- 8224 +/= 8225 +.. 8229 +,. 8230 +%0 8240 +1' 8242 +2' 8243 +3' 8244 +1" 8245 +2" 8246 +3" 8247 +Ca 8248 +<1 8249 +>1 8250 +:X 8251 +'- 8254 +/f 8260 +0S 8304 +4S 8308 +5S 8309 +6S 8310 +7S 8311 +8S 8312 +9S 8313 ++S 8314 +-S 8315 +=S 8316 +(S 8317 +)S 8318 +nS 8319 +0s 8320 +1s 8321 +2s 8322 +3s 8323 +4s 8324 +5s 8325 +6s 8326 +7s 8327 +8s 8328 +9s 8329 ++s 8330 +-s 8331 +=s 8332 +(s 8333 +)s 8334 +Li 8356 +Pt 8359 +W= 8361 +Eu 8364 +=R 8381 +=P 8381 +oC 8451 +co 8453 +oF 8457 +N0 8470 +PO 8471 +Rx 8478 +SM 8480 +TM 8482 +Om 8486 +AO 8491 +13 8531 +23 8532 +15 8533 +25 8534 +35 8535 +45 8536 +16 8537 +56 8538 +18 8539 +38 8540 +58 8541 +78 8542 +1R 8544 +2R 8545 +3R 8546 +4R 8547 +5R 8548 +6R 8549 +7R 8550 +8R 8551 +9R 8552 +aR 8553 +bR 8554 +cR 8555 +1r 8560 +2r 8561 +3r 8562 +4r 8563 +5r 8564 +6r 8565 +7r 8566 +8r 8567 +9r 8568 +ar 8569 +br 8570 +cr 8571 +<- 8592 +-! 8593 +-> 8594 +-v 8595 +<> 8596 +UD 8597 +<= 8656 +=> 8658 +== 8660 +FA 8704 +dP 8706 +TE 8707 +/0 8709 +DE 8710 +NB 8711 +(- 8712 +-) 8715 +*P 8719 ++Z 8721 +-2 8722 +-+ 8723 +*- 8727 +Ob 8728 +Sb 8729 +RT 8730 +0( 8733 +00 8734 +-L 8735 +-V 8736 +PP 8741 +AN 8743 +OR 8744 +(U 8745 +)U 8746 +In 8747 +DI 8748 +Io 8750 +.: 8756 +:. 8757 +:R 8758 +:: 8759 +?1 8764 +CG 8766 +?- 8771 +?= 8773 +?2 8776 +=? 8780 +HI 8787 +!= 8800 +=3 8801 +=< 8804 +>= 8805 +<* 8810 +*> 8811 +!< 8814 +!> 8815 +(C 8834 +)C 8835 +(_ 8838 +)_ 8839 +0. 8857 +02 8858 +-T 8869 +.P 8901 +:3 8942 +.3 8943 +Eh 8962 +<7 8968 +>7 8969 +7< 8970 +7> 8971 +NI 8976 +(A 8978 +TR 8981 +Iu 8992 +Il 8993 +</ 9001 +/> 9002 +Vs 9251 +1h 9280 +3h 9281 +2h 9282 +4h 9283 +1j 9286 +2j 9287 +3j 9288 +4j 9289 +1. 9352 +2. 9353 +3. 9354 +4. 9355 +5. 9356 +6. 9357 +7. 9358 +8. 9359 +9. 9360 +hh 9472 +HH 9473 +vv 9474 +VV 9475 +3- 9476 +3_ 9477 +3! 9478 +3/ 9479 +4- 9480 +4_ 9481 +4! 9482 +4/ 9483 +dr 9484 +dR 9485 +Dr 9486 +DR 9487 +dl 9488 +dL 9489 +Dl 9490 +LD 9491 +ur 9492 +uR 9493 +Ur 9494 +UR 9495 +ul 9496 +uL 9497 +Ul 9498 +UL 9499 +vr 9500 +vR 9501 +Vr 9504 +VR 9507 +vl 9508 +vL 9509 +Vl 9512 +VL 9515 +dh 9516 +dH 9519 +Dh 9520 +DH 9523 +uh 9524 +uH 9527 +Uh 9528 +UH 9531 +vh 9532 +vH 9535 +Vh 9538 +VH 9547 +FD 9585 +BD 9586 +TB 9600 +LB 9604 +FB 9608 +lB 9612 +RB 9616 +.S 9617 +:S 9618 +?S 9619 +fS 9632 +OS 9633 +RO 9634 +Rr 9635 +RF 9636 +RY 9637 +RH 9638 +RZ 9639 +RK 9640 +RX 9641 +sB 9642 +SR 9644 +Or 9645 +UT 9650 +uT 9651 +PR 9654 +Tr 9655 +Dt 9660 +dT 9661 +PL 9664 +Tl 9665 +Db 9670 +Dw 9671 +LZ 9674 +0m 9675 +0o 9678 +0M 9679 +0L 9680 +0R 9681 +Sn 9688 +Ic 9689 +Fd 9698 +Bd 9699 +*2 9733 +*1 9734 +<H 9756 +>H 9758 +0u 9786 +0U 9787 +SU 9788 +Fm 9792 +Ml 9794 +cS 9824 +cH 9825 +cD 9826 +cC 9827 +Md 9833 +M8 9834 +M2 9835 +Mb 9837 +Mx 9838 +MX 9839 +OK 10003 +XX 10007 +-X 10016 +IS 12288 +,_ 12289 +._ 12290 ++" 12291 ++_ 12292 +*_ 12293 +;_ 12294 +0_ 12295 +<+ 12298 +>+ 12299 +<' 12300 +>' 12301 +<" 12302 +>" 12303 +(" 12304 +)" 12305 +=T 12306 +=_ 12307 +(' 12308 +)' 12309 +(I 12310 +)I 12311 +-? 12316 +A5 12353 +a5 12354 +I5 12355 +i5 12356 +U5 12357 +u5 12358 +E5 12359 +e5 12360 +O5 12361 +o5 12362 +ka 12363 +ga 12364 +ki 12365 +gi 12366 +ku 12367 +gu 12368 +ke 12369 +ge 12370 +ko 12371 +go 12372 +sa 12373 +za 12374 +si 12375 +zi 12376 +su 12377 +zu 12378 +se 12379 +ze 12380 +so 12381 +zo 12382 +ta 12383 +da 12384 +ti 12385 +di 12386 +tU 12387 +tu 12388 +du 12389 +te 12390 +de 12391 +to 12392 +do 12393 +na 12394 +ni 12395 +nu 12396 +ne 12397 +no 12398 +ha 12399 +ba 12400 +pa 12401 +hi 12402 +bi 12403 +pi 12404 +hu 12405 +bu 12406 +pu 12407 +he 12408 +be 12409 +pe 12410 +ho 12411 +bo 12412 +po 12413 +ma 12414 +mi 12415 +mu 12416 +me 12417 +mo 12418 +yA 12419 +ya 12420 +yU 12421 +yu 12422 +yO 12423 +yo 12424 +ra 12425 +ri 12426 +ru 12427 +re 12428 +ro 12429 +wA 12430 +wa 12431 +wi 12432 +we 12433 +wo 12434 +n5 12435 +vu 12436 +"5 12443 +05 12444 +*5 12445 ++5 12446 +a6 12449 +A6 12450 +i6 12451 +I6 12452 +u6 12453 +U6 12454 +e6 12455 +E6 12456 +o6 12457 +O6 12458 +Ka 12459 +Ga 12460 +Ki 12461 +Gi 12462 +Ku 12463 +Gu 12464 +Ke 12465 +Ge 12466 +Ko 12467 +Go 12468 +Sa 12469 +Za 12470 +Si 12471 +Zi 12472 +Su 12473 +Zu 12474 +Se 12475 +Ze 12476 +So 12477 +Zo 12478 +Ta 12479 +Da 12480 +Ti 12481 +Di 12482 +TU 12483 +Tu 12484 +Du 12485 +Te 12486 +De 12487 +To 12488 +Do 12489 +Na 12490 +Ni 12491 +Nu 12492 +Ne 12493 +No 12494 +Ha 12495 +Ba 12496 +Pa 12497 +Hi 12498 +Bi 12499 +Pi 12500 +Hu 12501 +Bu 12502 +Pu 12503 +He 12504 +Be 12505 +Pe 12506 +Ho 12507 +Bo 12508 +Po 12509 +Ma 12510 +Mi 12511 +Mu 12512 +Me 12513 +Mo 12514 +YA 12515 +Ya 12516 +YU 12517 +Yu 12518 +YO 12519 +Yo 12520 +Ra 12521 +Ri 12522 +Ru 12523 +Re 12524 +Ro 12525 +WA 12526 +Wa 12527 +Wi 12528 +We 12529 +Wo 12530 +N6 12531 +Vu 12532 +KA 12533 +KE 12534 +Va 12535 +Vi 12536 +Ve 12537 +Vo 12538 +.6 12539 +-6 12540 +*6 12541 ++6 12542 +b4 12549 +p4 12550 +m4 12551 +f4 12552 +d4 12553 +t4 12554 +n4 12555 +l4 12556 +g4 12557 +k4 12558 +h4 12559 +j4 12560 +q4 12561 +x4 12562 +zh 12563 +ch 12564 +sh 12565 +r4 12566 +z4 12567 +c4 12568 +s4 12569 +a4 12570 +o4 12571 +e4 12572 +ai 12574 +ei 12575 +au 12576 +ou 12577 +an 12578 +en 12579 +aN 12580 +eN 12581 +er 12582 +i4 12583 +u4 12584 +iu 12585 +v4 12586 +nG 12587 +gn 12588 +1c 12832 +2c 12833 +3c 12834 +4c 12835 +5c 12836 +6c 12837 +7c 12838 +8c 12839 +9c 12840 +ff 64256 +fi 64257 +fl 64258 +ft 64261 +st 64262 diff --git a/.local/src/blesh/keymap/vi_test.sh b/.local/src/blesh/keymap/vi_test.sh new file mode 100644 index 0000000..2821515 --- /dev/null +++ b/.local/src/blesh/keymap/vi_test.sh @@ -0,0 +1,363 @@ +# this script is a part of blesh (https://github.com/akinomyoga/ble.sh) under BSD-3-Clause license +function ble/keymap:vi_test/decompose-state { + local spec=$1 + ind=${spec%%:*} str=${spec#*:} + if ((${#ind}==1)) && [[ $ind == [!0-9a-zA-Z] ]]; then + ind=${str%%"$ind"*} ind=${#ind} str=${str::ind}${str:ind+1} + mark= + elif ((${#ind}==2)) && [[ ${ind::1} == [!0-9a-zA-Z] && ${ind:1:1} == [!0-9a-zA-Z] ]]; then + local ind1=${ind::1} ind2=${ind:1:1} text + text=${str//"$ind2"} text=${text%%"$ind1"*} ind=${#text} + text=${str//"$ind1"} text=${text%%"$ind2"*} mark=${#text} + str=${str//["$ind"]*} + fi +} +function ble/keymap:vi_test/start-section { + section=$1 nsuccess=0 ntest=0 +} +function ble/keymap:vi_test/check { + local id=$1 initial=$2 kspecs=$3 final=$4 + local str ind mark + ble/keymap:vi_test/decompose-state "$initial"; local i=$ind in=$str ima=$mark + ble/keymap:vi_test/decompose-state "$final"; local f=$ind fin=$str fma=$mark + local nl=$'\n' NL=$'\e[7m^J\e[m' + ble-edit/content/reset "$in" edit + _ble_edit_ind=$i + [[ $ima ]] && _ble_edit_mark=$ima + local ret + ble-decode-kbd "$kspecs" + local ble_decode=${_ble_keymap_vi_test_ble_decode:-ble-decode-key} + "$ble_decode" $ret &>/dev/null + [[ $_ble_edit_ind == "$f" && $_ble_edit_str == "$fin" && ( ! $fma || $_ble_edit_mark == "$fma" ) ]]; local ext=$? + if ((ext==0)); then + ((ntest++,nsuccess++)) + else + ((ntest++)) + local esc_in=${in//$nl/"$NL"} + local esc_fin=${fin//$nl/"$NL"} + local esc_str=${_ble_edit_str//$nl/"$NL"} + ble/util/print "test($section/$id): keys = ($kspecs)" + ble/util/print " initial = \"$i:$esc_in\"" + ble/util/print " expected = \"$f:$esc_fin\"" + ble/util/print " result = \"$_ble_edit_ind:$esc_str\"" + fi >&2 + case $_ble_decode_keymap in + (vi_[ixo]map) + ble-decode-key $((_ble_decode_Ctrl|99)) &>/dev/null ;; + esac + return "$ext" +} +function ble/keymap:vi_test/show-summary { + local title=$section + if ((nsuccess==ntest)); then + local tip=$'\e[32mpassed\e[m' + else + local tip=$'\e[31mfailed\e[m' + fi + ble/util/print "# $title test: result $((nsuccess))/$((ntest)) $tip" +} +function ble/widget/vi-command:check-vi-mode/space { + ble/keymap:vi_test/start-section '<space>' + local str=$' 1234\n567890ab\n' + ble/keymap:vi_test/check 1 "4:$str" '4 SP' "9:$str" + ble/keymap:vi_test/check 2 "4:$str" 'd 4 SP' $'3: \n567890ab\n' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/cw { + ble/keymap:vi_test/start-section 'cw' + ble/keymap:vi_test/check A1 '@:cp ./foo.txt @ /tmp/' 'c w' '@:cp ./foo.txt @/tmp/' + ble/keymap:vi_test/check A2 '@:cp ./foo.tx@t /tmp/' 'c w' '@:cp ./foo.tx@ /tmp/' + ble/keymap:vi_test/check A3 '@:cp ./fo@o.txt /tmp/' 'c w' '@:cp ./fo@.txt /tmp/' + ble/keymap:vi_test/check A4 '@:cp ./foo.t@xt /tmp/' 'c w' '@:cp ./foo.t@ /tmp/' + ble/keymap:vi_test/check A5 '@:cp ./fo@o.txt /tmp/' 'c W' '@:cp ./fo@ /tmp/' + ble/keymap:vi_test/check B1a '@:123@ 456 789' 'c w' '@:123@456 789' + ble/keymap:vi_test/check B1b '@:123@ 456 789' '1 c w' '@:123@456 789' + ble/keymap:vi_test/check B1c '@:123@ 456 789' '2 c w' '@:123@789' + ble/keymap:vi_test/check B2a '@:12@3 456 789' 'c w' '@:12@ 456 789' + ble/keymap:vi_test/check B2b '@:12@3 456 789' '1 c w' '@:12@ 456 789' + ble/keymap:vi_test/check B2c '@:12@3 456 789' '2 c w' '@:12@ 789' + ble/keymap:vi_test/check B3a '@:@123 456 789' 'c w' '@:@ 456 789' + ble/keymap:vi_test/check B3b '@:@123 456 789' '1 c w' '@:@ 456 789' + ble/keymap:vi_test/check B3c '@:@123 456 789' '2 c w' '@:@ 789' + ble/keymap:vi_test/check B4a '@:ab@c///漢字' 'c w' '@:ab@///漢字' + ble/keymap:vi_test/check B4b '@:ab@c///漢字' '1 c w' '@:ab@///漢字' + ble/keymap:vi_test/check B4c '@:ab@c///漢字' '2 c w' '@:ab@漢字' + ble/keymap:vi_test/check B5a '@:@abc///漢字' 'c w' '@:@///漢字' + ble/keymap:vi_test/check B5b '@:@abc///漢字' '1 c w' '@:@///漢字' + ble/keymap:vi_test/check B5c '@:@abc///漢字' '2 c w' '@:@漢字' + ble/keymap:vi_test/check C1 $'@:123 456 @ \n\n789' 'c w' $'@:123 456 @\n\n789' + ble/keymap:vi_test/check C2 $'@:123 456 \n@\n789' 'c w' $'@:123 456 \n@\n789' + ble/keymap:vi_test/check C3 $'@:123 45@6 \n\n789' 'c w' $'@:123 45@ \n\n789' + ble/keymap:vi_test/check C4 $'@:123 456@ \n\n789\nabc' '2 c w' $'@:123 456@\n789\nabc' + ble/keymap:vi_test/check C5 $'@:123 45@6 \n\n789\nabc' '2 c w' $'@:123 45@\nabc' + ble/keymap:vi_test/check C6 $'@:123 4@56 \n\n789\nabc' '2 c w' $'@:123 4@\nabc' + ble/keymap:vi_test/check C7 $'@:123 456@ \n\n\n789\nabc' '2 c w' $'@:123 456@\n\n789\nabc' + ble/keymap:vi_test/check C8 $'@:123 45@6 \n\n\n789\nabc' '2 c w' $'@:123 45@\nabc' + ble/keymap:vi_test/check C9 $'@:123 4@56 \n\n\n789\nabc' '2 c w' $'@:123 4@\nabc' + ble/keymap:vi_test/check C9 $'@:123 456 \n\n@' '2 c w' $'@:123 456 \n\n@' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/search { + ble/keymap:vi_test/start-section '/ ? n N' + ble/keymap:vi_test/check A1a '@:ech@o abc abc abc' '/ a b c RET' '@:echo @abc abc abc' + ble/keymap:vi_test/check A1b '@:ech@o abc abc abc' '/ a b c RET n' '@:echo abc @abc abc' + ble/keymap:vi_test/check A1c '@:ech@o abc abc abc' '/ a b c RET 2 n' '@:echo abc abc @abc' + ble/keymap:vi_test/check A1d '@:ech@o abc abc abc' '/ a b c RET 2 n N' '@:echo abc @abc abc' + ble/keymap:vi_test/check A2a '@:echo@ abc abc abc' '/ a b c RET' '@:echo @abc abc abc' + ble/keymap:vi_test/check A2b '@:echo @abc abc abc' '/ a b c RET' '@:echo abc @abc abc' + ble/keymap:vi_test/check A2c '@:echo a@bc abc abc' '/ a b c RET' '@:echo abc @abc abc' + ble/keymap:vi_test/check A3a '@:echo abc@ abc abc' '? a b c RET' '@:echo @abc abc abc' + ble/keymap:vi_test/check A3b '@:echo abc @abc abc' '? a b c RET' '@:echo @abc abc abc' + ble/keymap:vi_test/check A3c '@:echo abc a@bc abc' '? a b c RET' '@:echo abc @abc abc' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/increment { + ble/keymap:vi_test/start-section '<C-a>, <C-x>' + ble/keymap:vi_test/check A1a '@:@123' 'C-a' '@:12@4' + ble/keymap:vi_test/check A1b '@:@123' 'C-x' '@:12@2' + ble/keymap:vi_test/check A1c '@:@-123' 'C-a' '@:-12@2' + ble/keymap:vi_test/check A1d '@:@-123' 'C-x' '@:-12@4' + ble/keymap:vi_test/check A2a '@:@ -123 0' 'C-a' '@: -12@2 0' + ble/keymap:vi_test/check A2b '@: @-123 0' 'C-a' '@: -12@2 0' + ble/keymap:vi_test/check A2c '@: -@123 0' 'C-a' '@: -12@2 0' + ble/keymap:vi_test/check A2d '@: -1@23 0' 'C-a' '@: -12@2 0' + ble/keymap:vi_test/check A2e '@: -12@3 0' 'C-a' '@: -12@2 0' + ble/keymap:vi_test/check A2f '@: -123@ 0' 'C-a' '@: -123 @1' + ble/keymap:vi_test/check A3a '@:@000' 'C-a' '@:00@1' + ble/keymap:vi_test/check A3b '@:@000' '1 0 C-a' '@:01@0' + ble/keymap:vi_test/check A3c '@:@000' '1 0 0 C-a' '@:10@0' + ble/keymap:vi_test/check A3d '@:@000' 'C-x' '@:-00@1' + ble/keymap:vi_test/check A3e '@:@000' '1 0 C-x' '@:-01@0' + ble/keymap:vi_test/check A3f '@:@000' '1 0 0 C-x' '@:-10@0' + ble/keymap:vi_test/check A3g '@:@099' '1 0 0 C-x' '@:-00@1' + ble/keymap:vi_test/check A3h '@:@099' '9 9 C-x' '@:00@0' + ble/keymap:vi_test/check A4a '@:-@0' 'C-a' '@:@1' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/macro { + local _ble_decode_keylog_depth=0 + local _ble_keymap_vi_test_ble_decode=ble-decode-char + local ble_decode_char_sync=1 + ble/keymap:vi_test/start-section 'qx..q' + ble/keymap:vi_test/check A1 '@:@123' 'q a A SP h e l l o @ESC q @ a' '@:123 hello hell@o' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/surround { + ble/keymap:vi_test/start-section 'surround' + ble/keymap:vi_test/check A1a '@:abcd @fghi jklm nopq' 'y s e a' '@:abcd @<fghi> jklm nopq' + ble/keymap:vi_test/check A1b '@:abcd @fghi jklm nopq' 'y s w a' '@:abcd @<fghi> jklm nopq' + ble/keymap:vi_test/check A1c '@:abcd @fghi jklm nopq' 'y s a w a' '@:abcd @<fghi> jklm nopq' + ble/keymap:vi_test/check A1d '@:abcd @ jklm nopq' 'y s 3 l a' '@:abcd @<> jklm nopq' + ble/keymap:vi_test/check A2a '@:abcd @fghi jklm nopq' 'v 3 l S a' '@:abcd @<fghi> jklm nopq' + ble/keymap:vi_test/check A2b '@:abcd @fghi jklm nopq' 'v 4 l S a' '@:abcd @<fghi >jklm nopq' + ble/keymap:vi_test/check A2c '@:abcd @fghi jklm nopq' 'h v 5 l S a' '@:abcd@< fghi >jklm nopq' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/xmap_txtobj_quote { + ble/keymap:vi_test/start-section 'xmap text object i" a"' + ble/keymap:vi_test/check A1a '@:ab@cd " fghi " jklm " nopq " rstu " vwxyz' 'v i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check A1b '@:abcd @" fghi " jklm " nopq " rstu " vwxyz' 'v i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check A1c '@:abcd " fghi@ " jklm " nopq " rstu " vwxyz' 'v i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check A1d '@:abcd " fghi @" jklm " nopq " rstu " vwxyz' 'v i " S a' '@:abcd " fghi "@< jklm >" nopq " rstu " vwxyz' + ble/keymap:vi_test/check A2a '@:ab@cd " fghi " jklm " nopq " rstu " vwxyz' 'v 2 i " S a' '@:abcd @<" fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check A2b '@:ab@cd " fghi " jklm " nopq " rstu " vwxyz' 'v a " S a' '@:abcd @<" fghi " >jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check A2c '@:ab@cd " fghi " jklm " nopq " rstu " vwxyz' 'v 2 a " S a' '@:abcd @<" fghi " >jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check A3a '@:ab@cd "" jklm " nopq " rstu " vwxyz' 'v i " S a' '@:abcd @<""> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check A3b '@:ab@cd "" jklm " nopq " rstu " vwxyz' 'v 2 i " S a' '@:abcd @<""> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check B1a '@:abcd@ " fghi " jklm " nopq " rstu " vwxyz' 'v l i " S a' '@:abcd@< " fghi " jklm >" nopq " rstu " vwxyz' + ble/keymap:vi_test/check B1b '@:abcd " fghi " jklm " nopq@ " rstu " vwxyz' 'v l i " S a' '@:abcd " fghi " jklm " nopq@< " rstu >" vwxyz' + ble/keymap:vi_test/check B1c '@:abc@d " fghi " jklm " nopq " rstu " vwxyz' 'v l i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check B1d '@:abcd " fgh@i " jklm " nopq " rstu " vwxyz' 'v l i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check B1e '@:abcd " fghi " @jklm " nopq " rstu " vwxyz' 'v l i " S a' '@:abcd " fghi " jklm "@< nopq >" rstu " vwxyz' + ble/keymap:vi_test/check B1f '@:abcd " fghi "@ jklm " nopq " rstu " vwxyz' 'v l i " S a' '@:abcd " fghi "@< jklm " nopq >" rstu " vwxyz' + ble/keymap:vi_test/check B2a '@:abcd@ " fghi " jklm " nopq " rstu " vwxyz' 'v l 2 i " S a' '@:abcd@< " fghi " jklm "> nopq " rstu " vwxyz' + ble/keymap:vi_test/check B2b '@:abcd " fghi " jklm " nopq@ " rstu " vwxyz' 'v l 2 i " S a' '@:abcd " fghi " jklm " nopq@< " rstu "> vwxyz' + ble/keymap:vi_test/check B2c '@:abc@d " fghi " jklm " nopq " rstu " vwxyz' 'v l 2 i " S a' '@:abcd @<" fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check B2d '@:abcd " fgh@i " jklm " nopq " rstu " vwxyz' 'v l 2 i " S a' '@:abcd @<" fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check B2e '@:abcd " fghi " @jklm " nopq " rstu " vwxyz' 'v l 2 i " S a' '@:abcd " fghi " jklm @<" nopq "> rstu " vwxyz' + ble/keymap:vi_test/check B2f '@:abcd " fghi "@ jklm " nopq " rstu " vwxyz' 'v l 2 i " S a' '@:abcd " fghi "@< jklm " nopq "> rstu " vwxyz' + ble/keymap:vi_test/check B3a '@:abcd@ " fghi " jklm " nopq " rstu " vwxyz' 'v l a " S a' '@:abcd@< " fghi " jklm " >nopq " rstu " vwxyz' + ble/keymap:vi_test/check B3b '@:abcd " fghi " jklm " nopq@ " rstu " vwxyz' 'v l a " S a' '@:abcd " fghi " jklm " nopq@< " rstu " >vwxyz' + ble/keymap:vi_test/check B3c '@:abc@d " fghi " jklm " nopq " rstu " vwxyz' 'v l a " S a' '@:abcd @<" fghi " >jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check B3d '@:abcd " fgh@i " jklm " nopq " rstu " vwxyz' 'v l a " S a' '@:abcd @<" fghi " >jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check B3e '@:abcd " fghi " @jklm " nopq " rstu " vwxyz' 'v l a " S a' '@:abcd " fghi " jklm @<" nopq " >rstu " vwxyz' + ble/keymap:vi_test/check B3f '@:abcd " fghi "@ jklm " nopq " rstu " vwxyz' 'v l a " S a' '@:abcd " fghi "@< jklm " nopq " >rstu " vwxyz' + ble/keymap:vi_test/check C1a '@:abc@d " fghi " jklm " nopq " rstu " vwxyz' 'v h i " S a' '@:ab@<cd> " fghi " jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C1b '@:abcd " @fghi " jklm " nopq " rstu " vwxyz' 'v h i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C1c '@:abcd " fghi@ " jklm " nopq " rstu " vwxyz' 'v h i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C1d '@:abcd " fghi @" jklm " nopq " rstu " vwxyz' 'v h i " S a' '@:abcd "@< fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C1e '@:abcd " fghi " jkl@m " nopq " rstu " vwxyz' 'v h i " S a' '@:abcd "@< fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C1f '@:abcd " fghi " jkl@m " nopq " rstu " vwxyz' 'v 5 h i " S a' '@:abcd "@< fghi " jklm> " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C2a '@:abc@d " fghi " jklm " nopq " rstu " vwxyz' 'v h 2 i " S a' '@:ab@<cd> " fghi " jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C2b '@:abcd " @fghi " jklm " nopq " rstu " vwxyz' 'v h 2 i " S a' '@:abcd @<" fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C2c '@:abcd " fghi@ " jklm " nopq " rstu " vwxyz' 'v h 2 i " S a' '@:abcd @<" fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C2d '@:abcd " fghi @" jklm " nopq " rstu " vwxyz' 'v h 2 i " S a' '@:abcd @<" fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C2e '@:abcd " fghi " jkl@m " nopq " rstu " vwxyz' 'v h 2 i " S a' '@:abcd @<" fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C2f '@:abcd " fghi " jkl@m " nopq " rstu " vwxyz' 'v 5 h 2 i " S a' '@:abcd @<" fghi " jklm> " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C3a '@:abc@d " fghi " jklm " nopq " rstu " vwxyz' 'v h a " S a' '@:ab@<cd> " fghi " jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C3b '@:abcd " @fghi " jklm " nopq " rstu " vwxyz' 'v h a " S a' '@:abcd @<" fghi " >jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C3c '@:abcd " fghi@ " jklm " nopq " rstu " vwxyz' 'v h a " S a' '@:abcd @<" fghi >" jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C3d '@:abcd " fghi @" jklm " nopq " rstu " vwxyz' 'v h a " S a' '@:abcd @<" fghi "> jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C3e '@:abcd " fghi " jkl@m " nopq " rstu " vwxyz' 'v h a " S a' '@:abcd @<" fghi " >jklm " nopq " rstu " vwxyz' + ble/keymap:vi_test/check C3f '@:abcd " fghi " jkl@m " nopq " rstu " vwxyz' 'v 5 h a " S a' '@:abcd @<" fghi " jklm> " nopq " rstu " vwxyz' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/txtobj_word { + ble/keymap:vi_test/start-section 'txtobj word omap' + ble/keymap:vi_test/check A1/iw '@:echo he@llo world "hello" "world"' 'd i w' '@:echo @ world "hello" "world"' + ble/keymap:vi_test/check A1/aw '@:echo he@llo world "hello" "world"' 'd a w' '@:echo @world "hello" "world"' + ble/keymap:vi_test/check A2/iw '@:echo hello@ world "hello" "world"' 'd i w' '@:echo hello@world "hello" "world"' + ble/keymap:vi_test/check A2/aw '@:echo hello@ world "hello" "world"' 'd a w' '@:echo hello@ "hello" "world"' + ble/keymap:vi_test/check A3/iw '@:echo hello world "he@llo" "world"' 'd i w' '@:echo hello world "@" "world"' + ble/keymap:vi_test/check A3/aw '@:echo hello world "he@llo" "world"' 'd a w' '@:echo hello world "@" "world"' + ble/keymap:vi_test/check A4/iw '@:echo hello world @"hello" "world"' 'd i w' '@:echo hello world @hello" "world"' + ble/keymap:vi_test/check A4/aw '@:echo hello world @"hello" "world"' 'd a w' '@:echo hello world@hello" "world"' + ble/keymap:vi_test/check A5/iw '@:echo hello world "hello@" "world"' 'd i w' '@:echo hello world "hello@ "world"' + ble/keymap:vi_test/check A5/aw '@:echo hello world "hello@" "world"' 'd a w' '@:echo hello world "hello@"world"' + ble/keymap:vi_test/check A1/2iw '@:echo he@llo world "hello" "world"' 'd 2 i w' '@:echo @world "hello" "world"' + ble/keymap:vi_test/check A1/2aw '@:echo he@llo world "hello" "world"' 'd 2 a w' '@:echo @"hello" "world"' + ble/keymap:vi_test/check A2/2iw '@:echo hello@ world "hello" "world"' 'd 2 i w' '@:echo hello@ "hello" "world"' + ble/keymap:vi_test/check A2/2aw '@:echo hello@ world "hello" "world"' 'd 2 a w' '@:echo hello@hello" "world"' + ble/keymap:vi_test/check A3/2iw '@:echo hello world "he@llo" "world"' 'd 2 i w' '@:echo hello world "@ "world"' + ble/keymap:vi_test/check A3/2aw '@:echo hello world "he@llo" "world"' 'd 2 a w' '@:echo hello world "@"world"' + ble/keymap:vi_test/check A4/2iw '@:echo hello world @"hello" "world"' 'd 2 i w' '@:echo hello world @" "world"' + ble/keymap:vi_test/check A4/2aw '@:echo hello world @"hello" "world"' 'd 2 a w' '@:echo hello world@" "world"' + ble/keymap:vi_test/check A5/2iw '@:echo hello world "hello@" "world"' 'd 2 i w' '@:echo hello world "hello@"world"' + ble/keymap:vi_test/check A5/2aw '@:echo hello world "hello@" "world"' 'd 2 a w' '@:echo hello world "hello@world"' + ble/keymap:vi_test/check A6/iw $'@:echo@ \n hello world' 'd i w' $'@:ech@o\n hello world' + ble/keymap:vi_test/check A6/aw $'@:echo@ \n hello world' 'd a w' $'@:echo@ world' + ble/keymap:vi_test/check A7.2/iw $'@:echo\n@\nhello\n\nworld\nZ' 'd i w' $'@:echo\n@\nhello\n\nworld\nZ' + ble/keymap:vi_test/check A7.2/aw $'@:echo\n@\nhello\n\nworld\nZ' 'd a w' $'@:echo\n@\nworld\nZ' + ble/keymap:vi_test/check A7.2/2iw $'@:echo\n@\nhello\n\nworld\nZ' 'd 2 i w' $'@:echo\n@\nworld\nZ' + ble/keymap:vi_test/check A7.2/2aw $'@:echo\n@\nhello\n\nworld\nZ' 'd 2 a w' $'@:echo\n@Z' + ble/keymap:vi_test/check A7.1/1diw $'@:echo\n@\nhello\nworld\nZ' 'd 1 i w' $'@:echo\n@\nhello\nworld\nZ' + ble/keymap:vi_test/check A7.1/2diw $'@:echo\n@\nhello\nworld\nZ' 'd 2 i w' $'@:echo\n@world\nZ' + ble/keymap:vi_test/check A7.1/3diw $'@:echo\n@\nhello\nworld\nZ' 'd 3 i w' $'@:echo\n@Z' + ble/keymap:vi_test/check A7.2/1diw $'@:echo\n@\nhello\n\nworld\nZ' 'd 1 i w' $'@:echo\n@\nhello\n\nworld\nZ' + ble/keymap:vi_test/check A7.2/2diw $'@:echo\n@\nhello\n\nworld\nZ' 'd 2 i w' $'@:echo\n@\nworld\nZ' + ble/keymap:vi_test/check A7.2/3diw $'@:echo\n@\nhello\n\nworld\nZ' 'd 3 i w' $'@:echo\n@world\nZ' + ble/keymap:vi_test/check A7.2/4diw $'@:echo\n@\nhello\n\nworld\nZ' 'd 4 i w' $'@:echo\n@Z' + ble/keymap:vi_test/check A7.3/1diw $'@:echo\n@\nhello\n\n\nworld\nZ' 'd 1 i w' $'@:echo\n@\nhello\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.3/2diw $'@:echo\n@\nhello\n\n\nworld\nZ' 'd 2 i w' $'@:echo\n@\n\nworld\nZ' + ble/keymap:vi_test/check A7.3/3diw $'@:echo\n@\nhello\n\n\nworld\nZ' 'd 3 i w' $'@:echo\n@\nworld\nZ' + ble/keymap:vi_test/check A7.3/4diw $'@:echo\n@\nhello\n\n\nworld\nZ' 'd 4 i w' $'@:echo\n@Z' + ble/keymap:vi_test/check A7.4/1diw $'@:echo\n@\nhello\n\n\n\nworld\nZ' 'd 1 i w' $'@:echo\n@\nhello\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.4/2diw $'@:echo\n@\nhello\n\n\n\nworld\nZ' 'd 2 i w' $'@:echo\n@\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.4/3diw $'@:echo\n@\nhello\n\n\n\nworld\nZ' 'd 3 i w' $'@:echo\n@\n\nworld\nZ' + ble/keymap:vi_test/check A7.4/4diw $'@:echo\n@\nhello\n\n\n\nworld\nZ' 'd 4 i w' $'@:echo\n@world\nZ' + ble/keymap:vi_test/check A7.4/5diw $'@:echo\n@\nhello\n\n\n\nworld\nZ' 'd 5 i w' $'@:echo\n@Z' + ble/keymap:vi_test/check A7.5/1diw $'@:echo\n@\nhello\n\n\n\n\nworld\nZ' 'd 1 i w' $'@:echo\n@\nhello\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.5/2diw $'@:echo\n@\nhello\n\n\n\n\nworld\nZ' 'd 2 i w' $'@:echo\n@\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.5/3diw $'@:echo\n@\nhello\n\n\n\n\nworld\nZ' 'd 3 i w' $'@:echo\n@\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.5/4diw $'@:echo\n@\nhello\n\n\n\n\nworld\nZ' 'd 4 i w' $'@:echo\n@\nworld\nZ' + ble/keymap:vi_test/check A7.5/5diw $'@:echo\n@\nhello\n\n\n\n\nworld\nZ' 'd 5 i w' $'@:echo\n@Z' + local A7_a=$'@:echo\n@\nhello\n\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/1ciw "$A7_a" 'c 1 i w' $'@:echo\n@\nhello\n\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/2ciw "$A7_a" 'c 2 i w' $'@:echo\n@\n\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/3ciw "$A7_a" 'c 3 i w' $'@:echo\n@\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/4ciw "$A7_a" 'c 4 i w' $'@:echo\n@\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/5ciw "$A7_a" 'c 5 i w' $'@:echo\n@\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/6ciw "$A7_a" 'c 6 i w' $'@:echo\n@\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/7ciw "$A7_a" 'c 7 i w' $'@:echo\n@\nworld\nZ' + ble/keymap:vi_test/check A7.a/8ciw "$A7_a" 'c 8 i w' $'@:echo\n@\nZ' + ble/keymap:vi_test/check A7.a/1diw "$A7_a" 'd 1 i w' $'@:echo\n@\nhello\n\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/2diw "$A7_a" 'd 2 i w' $'@:echo\n@\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/3diw "$A7_a" 'd 3 i w' $'@:echo\n@\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/4diw "$A7_a" 'd 4 i w' $'@:echo\n@\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/5diw "$A7_a" 'd 5 i w' $'@:echo\n@\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/6diw "$A7_a" 'd 6 i w' $'@:echo\n@\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/7diw "$A7_a" 'd 7 i w' $'@:echo\n@world\nZ' + ble/keymap:vi_test/check A7.a/8diw "$A7_a" 'd 8 i w' $'@:echo\n@Z' + ble/keymap:vi_test/check A7.a/1caw "$A7_a" 'c 1 a w' $'@:echo\n@\n\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/2caw "$A7_a" 'c 2 a w' $'@:echo\n@\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/3caw "$A7_a" 'c 3 a w' $'@:echo\n@\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/4caw "$A7_a" 'c 4 a w' $'@:echo\n@\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/5caw "$A7_a" 'c 5 a w' $'@:echo\n@\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/6caw "$A7_a" 'c 6 a w' $'@:echo\n@\nZ' + ble/keymap:vi_test/check A7.a/1daw "$A7_a" 'd 1 a w' $'@:echo\n@\n\n\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/2daw "$A7_a" 'd 2 a w' $'@:echo\n@\n\n\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/3daw "$A7_a" 'd 3 a w' $'@:echo\n@\n\n\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/4daw "$A7_a" 'd 4 a w' $'@:echo\n@\n\n\nworld\nZ' + ble/keymap:vi_test/check A7.a/5daw "$A7_a" 'd 5 a w' $'@:echo\n@\nworld\nZ' + ble/keymap:vi_test/check A7.a/6daw "$A7_a" 'd 6 a w' $'@:echo\n@Z' + ble/keymap:vi_test/check A8.0/2aw $'@:echo\n@\nhello\n\nworld\n' 'd 2 a w' $'@:@echo' + ble/keymap:vi_test/check A8.2/2aw $'@: echo\n@\nhello\n\nworld\n' 'd 2 a w' $'@: @echo' + ble/keymap:vi_test/check A9.1/ciw $'@:@ \necho' 'c i w' $'@:@\necho' + ble/keymap:vi_test/check A9.2/ciw $'@:@\n echo' 'c i w' $'@:@\n echo' + ble/keymap:vi_test/show-summary + ble/keymap:vi_test/start-section 'txtobj word xmap' + ble/keymap:vi_test/check B1/viw.1 '@:echo he@llo world "hello" "world"' 'v i w S a' '@:echo @<hello> world "hello" "world"' + ble/keymap:vi_test/check B1/vaw.1 '@:echo he@llo world "hello" "world"' 'v a w S a' '@:echo @<hello >world "hello" "world"' + ble/keymap:vi_test/check B2/viw.2 '@:echo hello@ world "hello" "world"' 'v i w S a' '@:echo hello@< >world "hello" "world"' + ble/keymap:vi_test/check B2/vaw.2 '@:echo hello@ world "hello" "world"' 'v a w S a' '@:echo hello@< world> "hello" "world"' + ble/keymap:vi_test/check B3/viw.3 '@:echo hello world "he@llo" "world"' 'v i w S a' '@:echo hello world "@<hello>" "world"' + ble/keymap:vi_test/check B3/vaw.3 '@:echo hello world "he@llo" "world"' 'v a w S a' '@:echo hello world "@<hello>" "world"' + ble/keymap:vi_test/check B4/viw.4 '@:echo hello world @"hello" "world"' 'v i w S a' '@:echo hello world @<">hello" "world"' + ble/keymap:vi_test/check B4/vaw.4 '@:echo hello world @"hello" "world"' 'v a w S a' '@:echo hello world@< ">hello" "world"' + ble/keymap:vi_test/check B5/viw.5 '@:echo hello world "hello@" "world"' 'v i w S a' '@:echo hello world "hello@<"> "world"' + ble/keymap:vi_test/check B5/vaw.5 '@:echo hello world "hello@" "world"' 'v a w S a' '@:echo hello world "hello@<" >"world"' + ble/keymap:vi_test/check B1/v2iw.1 '@:echo he@llo world "hello" "world"' 'v 2 i w S a' '@:echo @<hello >world "hello" "world"' + ble/keymap:vi_test/check B1/v2aw.1 '@:echo he@llo world "hello" "world"' 'v 2 a w S a' '@:echo @<hello world >"hello" "world"' + ble/keymap:vi_test/check B2/v2iw.2 '@:echo hello@ world "hello" "world"' 'v 2 i w S a' '@:echo hello@< world> "hello" "world"' + ble/keymap:vi_test/check B2/v2aw.2 '@:echo hello@ world "hello" "world"' 'v 2 a w S a' '@:echo hello@< world ">hello" "world"' + ble/keymap:vi_test/check B3/v2iw.3 '@:echo hello world "he@llo" "world"' 'v 2 i w S a' '@:echo hello world "@<hello"> "world"' + ble/keymap:vi_test/check B3/v2aw.3 '@:echo hello world "he@llo" "world"' 'v 2 a w S a' '@:echo hello world "@<hello" >"world"' + ble/keymap:vi_test/check B4/v2iw.4 '@:echo hello world @"hello" "world"' 'v 2 i w S a' '@:echo hello world @<"hello>" "world"' + ble/keymap:vi_test/check B4/v2aw.4 '@:echo hello world @"hello" "world"' 'v 2 a w S a' '@:echo hello world@< "hello>" "world"' + ble/keymap:vi_test/check B5/v2iw.5 '@:echo hello world "hello@" "world"' 'v 2 i w S a' '@:echo hello world "hello@<" >"world"' + ble/keymap:vi_test/check B5/v2aw.5 '@:echo hello world "hello@" "world"' 'v 2 a w S a' '@:echo hello world "hello@<" ">world"' + ble/keymap:vi_test/check B2/v1hiw '@:echo hello wo@rld' 'v 1 h i w S a' '@:echo hello @<wor>ld' + ble/keymap:vi_test/check B2/v2hiw '@:echo hello wo@rld' 'v 2 h i w S a' '@:echo hello@< wor>ld' + ble/keymap:vi_test/check B2/v3hiw '@:echo hello wo@rld' 'v 3 h i w S a' '@:echo hello@< wor>ld' + ble/keymap:vi_test/check B2/v4hiw '@:echo hello wo@rld' 'v 4 h i w S a' '@:echo @<hello wor>ld' + ble/keymap:vi_test/check B2/v1haw '@:echo hello wo@rld' 'v 1 h a w S a' '@:echo hello@< wor>ld' + ble/keymap:vi_test/check B2/v2haw '@:echo hello wo@rld' 'v 2 h a w S a' '@:echo @<hello wor>ld' + ble/keymap:vi_test/check B2/v3haw '@:echo hello wo@rld' 'v 3 h a w S a' '@:echo @<hello wor>ld' + ble/keymap:vi_test/check B2/v4haw '@:echo hello wo@rld' 'v 4 h a w S a' '@:echo@< hello wor>ld' + ble/keymap:vi_test/check B1/v1haw '@:echo he@llo' 'v 1 h a w S a' '@:echo@< hel>lo' + ble/keymap:vi_test/check B1/v2haw '@:echo he@llo' 'v 2 h a w S a' '@:@<echo hel>lo' + ble/keymap:vi_test/check B1/v3haw '@:echo he@llo' 'v 3 h a w S a' '@:e@<cho hel>lo' + ble/keymap:vi_test/check B1/v4haw '@:echo he@llo' 'v 4 h a w S a' '@:e@<cho hel>lo' + ble/keymap:vi_test/check Bn/viw $'@:@echo hello\necho world' 'v $ o $ i w c' $'@:echo hell@echo world' + ble/keymap:vi_test/check Bn/viw $'@:@echo hello \necho world' 'v $ o $ i w c' $'@:echo hello@\necho world' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode/op.2018-02-22 { + ble/keymap:vi_test/start-section 'op.2018-02-22' + ble/keymap:vi_test/check A0 $'@:12@345\n67890\n' 'y y p' $'@:12345\n@12345\n67890\n' + ble/keymap:vi_test/check B1 $'@:12@345\n67890\n' 'Y' $'@:12@345\n67890\n' + ble/keymap:vi_test/check B2 $'@:12@345\n67890\n' 'y y' $'@:12@345\n67890\n' + ble/keymap:vi_test/check C $'@:\n12@34567\n1あ2345\n12い345\n123う45\n1234え5\n' 'C-v 4 j l d' $'@:\n12@567\n1 345\n12345\n12 45\n12え5\n' + ble/keymap:vi_test/show-summary +} +function ble/widget/vi-command:check-vi-mode { + local original_str=$_ble_edit_str + local original_ind=$_ble_edit_ind + local original_mark=$_ble_edit_mark + local original_mark_active=$_ble_edit_mark_active + _ble_edit_line_disabled=1 ble/widget/.insert-newline # #D1800 pair=leave-command-layout + ble/util/buffer.flush >&2 + local section ntest nsuccess + ble/widget/vi-command:check-vi-mode/space + ble/widget/vi-command:check-vi-mode/cw + ble/widget/vi-command:check-vi-mode/search + ble/widget/vi-command:check-vi-mode/increment + ble/widget/vi-command:check-vi-mode/macro + ble/widget/vi-command:check-vi-mode/surround + ble/widget/vi-command:check-vi-mode/xmap_txtobj_quote + ble/widget/vi-command:check-vi-mode/op.2018-02-22 + ble/widget/vi-command:check-vi-mode/txtobj_word + ble-edit/content/reset "$original_str" edit + _ble_edit_ind=$original_ind + _ble_edit_mark=$original_mark + _ble_edit_mark_active=$original_mark_active + ble/edit/leave-command-layout # #D1800 pair=.insert-newline + return 0 +} +function ble/widget/vi_imap/check-vi-mode { + ble/widget/vi_imap/normal-mode + ble/widget/vi-command:check-vi-mode + return 0 +} +ble-bind -m vi_imap -f 'C-\ C-\' vi_imap/check-vi-mode +ble-bind -m vi_nmap -f 'C-\ C-\' vi-command:check-vi-mode |