keymap.emacs.sh (10020B)
1 #!/bin/bash 2 3 # include guard 4 ble/is-function ble-edit/bind/load-editing-mode:emacs && return 0 5 function ble-edit/bind/load-editing-mode:emacs { :; } 6 7 # 2015-12-09 keymap cache should be updated due to the refactoring. 8 # 2019-01-18 keymap cache should be updated for recent changes 9 # 2019-03-21 keymap cache should be updated for recent changes 10 # 2020-04-29 force update (rename ble-decode/keymap/.register) 11 # 2021-01-25 force update (change mapping of C-w and M-w) 12 # 2021-04-26 force update (rename ble/decode/keymap#.register) 13 # 2021-09-23 force update (change to nsearch and bind-history) 14 15 # vi functions referenced from core-decode.emacs-rlfunc.txt 16 ble/util/autoload "$_ble_base/lib/keymap.vi.sh" \ 17 ble/widget/vi-rlfunc/{prev,end,next}-word \ 18 ble/widget/vi-command/{forward,backward}-{v,u}word \ 19 ble/widget/vi-command/forward-{v,u}word-end 20 21 bleopt/declare -v keymap_emacs_mode_string_multiline $'\e[1m-- MULTILINE --\e[m' 22 23 #------------------------------------------------------------------------------ 24 25 _ble_keymap_emacs_white_list=( 26 self-insert 27 batch-insert 28 nop 29 magic-space magic-slash 30 copy{,-forward,-backward}-{c,f,s,u}word 31 copy-region{,-or} 32 clear-screen 33 command-help 34 display-shell-version 35 redraw-line 36 # delete-backward-{c,f,s,u}word 37 # delete-bacward-char 38 ) 39 function ble/keymap:emacs/is-command-white { 40 if [[ $1 == ble/widget/self-insert ]]; then 41 # frequently used command is checked first 42 return 0 43 elif [[ $1 == ble/widget/* ]]; then 44 local IFS=$_ble_term_IFS 45 local cmd=${1#ble/widget/}; cmd=${cmd%%["$_ble_term_IFS"]*} 46 [[ $cmd == emacs/* || " ${_ble_keymap_emacs_white_list[*]} " == *" $cmd "* ]] && return 0 47 fi 48 return 1 49 } 50 51 function ble/widget/emacs/__before_widget__ { 52 if ! ble/keymap:emacs/is-command-white "$WIDGET"; then 53 ble-edit/undo/add 54 fi 55 } 56 57 #------------------------------------------------------------------------------ 58 # 注意: ble/widget/emacs/* の名称の編集関数では、 59 # 必要に応じて手動で ble-edit/undo/add を呼び出さなければならない。 60 61 function ble/widget/emacs/undo { 62 local arg; ble-edit/content/get-arg 1 63 ble-edit/undo/undo "$arg" || ble/widget/.bell 'no more older undo history' 64 } 65 function ble/widget/emacs/redo { 66 local arg; ble-edit/content/get-arg 1 67 ble-edit/undo/redo "$arg" || ble/widget/.bell 'no more recent undo history' 68 } 69 function ble/widget/emacs/revert { 70 local arg; ble-edit/content/clear-arg 71 ble-edit/undo/revert 72 } 73 74 #------------------------------------------------------------------------------ 75 # mode name 76 # 77 # mode name の更新は基本的に __after_widget__ で行う。 78 # 但し、_ble_decode_{char,key}__hook 経由で実行されると、 79 # __after_widget__ は実行されないので、 80 # その様な編集コマンドについてだけは個別に update-mode-indicator を呼び出す。 81 # 82 83 function ble/keymap:emacs/.get-emacs-keymap { 84 ble/prompt/unit/add-hash '$_ble_decode_keymap,${_ble_decode_keymap_stack[*]}' 85 local i=${#_ble_decode_keymap_stack[@]} 86 keymap=$_ble_decode_keymap 87 while [[ $keymap != vi_?map && $keymap != emacs ]]; do 88 ((i--)) || return 1 89 keymap=${_ble_decode_keymap_stack[i]} 90 done 91 [[ $keymap == emacs ]] 92 } 93 94 bleopt/declare -v prompt_emacs_mode_indicator '\q{keymap:emacs/mode-indicator}' 95 function bleopt/check:prompt_emacs_mode_indicator { 96 local bleopt_prompt_emacs_mode_indicator=$value 97 [[ $_ble_attached ]] && ble/keymap:emacs/update-mode-indicator 98 return 0 99 } 100 101 _ble_keymap_emacs_mode_indicator_data=() 102 function ble/prompt/unit:_ble_keymap_emacs_mode_indicator/update { 103 local trace_opts=truncate:relative:noscrc:ansi 104 local prompt_rows=1 105 local prompt_cols=${COLUMNS:-80} 106 ((prompt_cols&&prompt_cols--)) 107 local "${_ble_prompt_cache_vars[@]/%/=}" # WA #D1570 checked 108 ble/prompt/unit:{section}/update _ble_keymap_emacs_mode_indicator "$bleopt_prompt_emacs_mode_indicator" "$trace_opts" 109 } 110 111 function ble/keymap:emacs/update-mode-indicator { 112 local keymap 113 ble/keymap:emacs/.get-emacs-keymap || return 0 114 115 # prefilter by _ble_edit_str/_ble_edit_arg/_ble_edit_kbdmacro_record 116 local opt_multiline= 117 [[ $_ble_edit_str == *$'\n'* ]] && opt_multiline=1 118 local footprint=$opt_multiline:$_ble_edit_arg:$_ble_edit_kbdmacro_record 119 [[ $footprint == "$_ble_keymap_emacs_modeline" ]] && return 0 120 _ble_keymap_emacs_modeline=$footprint 121 122 # prompt_emacs_mode_indicator 123 local version=$COLUMNS,$_ble_edit_lineno,$_ble_history_count,$_ble_edit_CMD 124 local prompt_hashref_base='$version' 125 ble/prompt/unit#update _ble_keymap_emacs_mode_indicator 126 local ret; ble/prompt/unit:{section}/get _ble_keymap_emacs_mode_indicator; local str=$ret 127 128 [[ $_ble_edit_arg ]] && 129 str=${str:+"$str "}$'(arg: \e[1;34m'$_ble_edit_arg$'\e[m)' 130 [[ $_ble_edit_kbdmacro_record ]] && 131 str=${str:+"$str "}$'\e[1;31mREC\e[m' 132 133 ble/edit/info/default ansi "$str" 134 } 135 blehook internal_PRECMD!=ble/keymap:emacs/update-mode-indicator 136 137 ## @fn ble/prompt/backslash:keymap:emacs/mode-indicator 138 function ble/prompt/backslash:keymap:emacs/mode-indicator { 139 ble/prompt/unit/add-hash '$_ble_edit_str' 140 [[ $_ble_edit_str == *$'\n'* ]] || return 0 141 142 ble/prompt/unit/add-hash '$bleopt_keymap_emacs_mode_string_multiline' 143 local str=$bleopt_keymap_emacs_mode_string_multiline 144 145 # 他の付加情報がない時にだけ keybinding のヒントを出す 146 ble/prompt/unit/add-hash '${_ble_edit_arg:+1}${_ble_edit_kbdmacro_record:+1}' 147 if [[ ! ${_ble_edit_arg:+1}${_ble_edit_kbdmacro_record:+1} ]]; then 148 local keybinding_C_m=${_ble_decode_emacs_kmap_[_ble_decode_Ctrl|0x6d]} 149 local keybinding_C_j=${_ble_decode_emacs_kmap_[_ble_decode_Ctrl|0x6a]} 150 [[ $keybinding_C_m == *:ble/widget/accept-single-line-or-newline ]] && 151 [[ $keybinding_C_j == *:ble/widget/accept-line ]] && 152 str=${str:+"$str "}$'(\e[35mRET\e[m or \e[35mC-m\e[m: insert a newline, \e[35mC-j\e[m: run)' 153 fi 154 155 [[ ! $str ]] || ble/prompt/print "$str" 156 } 157 158 function ble/widget/emacs/__after_widget__ { 159 ble/keymap:emacs/update-mode-indicator 160 } 161 162 # quoted-insert 163 function ble/widget/emacs/quoted-insert-char { 164 _ble_edit_mark_active= 165 _ble_decode_char__hook=ble/widget/emacs/quoted-insert-char.hook 166 return 147 167 } 168 function ble/widget/emacs/quoted-insert-char.hook { 169 ble/widget/quoted-insert-char.hook 170 ble/keymap:emacs/update-mode-indicator 171 } 172 function ble/widget/emacs/quoted-insert { 173 _ble_edit_mark_active= 174 _ble_decode_key__hook=ble/widget/emacs/quoted-insert.hook 175 return 147 176 } 177 function ble/widget/emacs/quoted-insert.hook { 178 ble/widget/quoted-insert.hook 179 ble/keymap:emacs/update-mode-indicator 180 } 181 182 function ble/widget/emacs/bracketed-paste { 183 ble/widget/bracketed-paste 184 _ble_edit_bracketed_paste_proc=ble/widget/emacs/bracketed-paste.proc 185 return 147 186 } 187 function ble/widget/emacs/bracketed-paste.proc { 188 ble/widget/bracketed-paste.proc "$@" 189 ble/keymap:emacs/update-mode-indicator 190 } 191 192 #------------------------------------------------------------------------------ 193 194 function ble-decode/keymap:emacs/define { 195 #---------------------------------------------------------------------------- 196 # common bindings + modifications 197 198 local ble_bind_nometa= 199 ble-decode/keymap:safe/bind-common 200 ble-decode/keymap:safe/bind-history 201 ble-decode/keymap:safe/bind-complete 202 ble-decode/keymap:safe/bind-arg 203 204 # charwise operations 205 ble-bind -f 'C-d' 'delete-region-or delete-forward-char-or-exit' 206 207 # history 208 ble-bind -f 'M-^' history-expand-line 209 ble-bind -f 'SP' magic-space 210 ble-bind -f '/' magic-slash 211 212 #---------------------------------------------------------------------------- 213 214 ble-bind -f __attach__ safe/__attach__ 215 ble-bind -f __before_widget__ emacs/__before_widget__ 216 ble-bind -f __after_widget__ emacs/__after_widget__ 217 ble-bind -f __line_limit__ __line_limit__ 218 219 # accept/cancel 220 ble-bind -f 'C-c' discard-line 221 ble-bind -f 'C-j' accept-line 222 ble-bind -f 'C-RET' accept-line 223 ble-bind -f 'C-m' accept-single-line-or-newline 224 ble-bind -f 'RET' accept-single-line-or-newline 225 ble-bind -f 'C-o' accept-and-next 226 ble-bind -f 'C-x C-e' edit-and-execute-command 227 ble-bind -f 'M-#' insert-comment 228 ble-bind -f 'M-C-e' shell-expand-line 229 ble-bind -f 'M-&' tilde-expand 230 ble-bind -f 'C-g' bell 231 ble-bind -f 'C-x C-g' bell 232 ble-bind -f 'C-M-g' bell 233 234 # shell functions 235 ble-bind -f 'C-l' clear-screen 236 ble-bind -f 'C-M-l' redraw-line 237 ble-bind -f 'f1' command-help 238 ble-bind -f 'C-x C-v' display-shell-version 239 ble-bind -c 'C-z' fg 240 ble-bind -c 'M-z' fg 241 242 ble-bind -f 'C-\' bell 243 ble-bind -f 'C-^' bell 244 245 #---------------------------------------------------------------------------- 246 247 # undo 248 ble-bind -f 'C-_' emacs/undo 249 ble-bind -f 'C-DEL' emacs/undo 250 ble-bind -f 'C-BS' emacs/undo 251 ble-bind -f 'C-/' emacs/undo 252 ble-bind -f 'C-x u' emacs/undo 253 ble-bind -f 'C-x C-u' emacs/undo 254 ble-bind -f 'C-x U' emacs/redo 255 ble-bind -f 'C-x C-S-u' emacs/redo 256 ble-bind -f 'M-r' emacs/revert 257 258 # mode name 259 ble-bind -f 'C-q' emacs/quoted-insert 260 ble-bind -f 'C-v' emacs/quoted-insert 261 ble-bind -f paste_begin emacs/bracketed-paste 262 } 263 264 function ble-decode/keymap:emacs/initialize { 265 local fname_keymap_cache=$_ble_base_cache/keymap.emacs 266 if [[ -s $fname_keymap_cache && 267 $fname_keymap_cache -nt $_ble_base/lib/keymap.emacs.sh && 268 $fname_keymap_cache -nt $_ble_base/lib/init-cmap.sh ]]; then 269 source "$fname_keymap_cache" && return 0 270 fi 271 272 ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs..." 273 274 { 275 ble/decode/keymap#load isearch dump 276 ble/decode/keymap#load nsearch dump 277 ble/decode/keymap#load emacs dump 278 } 3>| "$fname_keymap_cache" 279 280 ble/edit/info/immediate-show text "ble.sh: updating cache/keymap.emacs... done" 281 } 282 283 ble-decode/keymap:emacs/initialize 284 blehook/invoke keymap_load 285 blehook/invoke keymap_emacs_load 286 return 0