sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

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