All pastes #1711428 Raw Edit

_migemo_complete

public shellscript v1 · immutable
#1711428 ·published 2009-12-11 20:52 UTC
rendered paste body
#autoload# migemo補完の completer.# NOTE:# 現状はファイル名補完のみ動作する為、# 以下のように通常の completer と併用して使用する.##   zstyle ":completion:::::" completer _complete _migemo_complete## matcher specifications は無効.# EXAMPLE:# 補完前の入力                      -> 補完候補パターン# [input1]:[input2][cursor][input3] -> [regex1].*[regex2].*[regex3]# TODO:# zstyle化# :: を : として扱う# 全角英字を含めて case-insensitive にする[[ _matcher_num -gt 1 ]] && return 1local dounfunctionlocal ret=1local _matcher='m:?='	# これがないと compfiles の時点で補完候補が絞られ過ぎるlocal -A migemo_resultlocal -A matching_resultlocal -A matching_result_pat_id# TODO: 脱coprocif [[ -z $jobtexts[(r)_migemo_program] ]]; then  # $jobtexts をこの関数名で識別する  _migemo_program() {    # `coproc 関数' とすると、exec なしでは別の coprocess 起動時に残ってしまう    exec sh -c 'nkf -Weu |migemo -t egrep /usr/share/migemo/migemo-dict |nkf -Ewu'  }  unsetopt monitor	# coproc の出力を抑止(NOTE: 他に coprocess があると黙って終わってしまう)  coproc _migemo_programfi_call_migemo() {  if (( ! $+migemo_result[$1] )); then    print -p - "$1"    read -p    migemo_result[$1]=$REPLY  else    REPLY=$migemo_result[$1]  fi}{  if (( ! $+functions[compadd] )); then    # migemize した compadd 関数を builtin に代わって一時的に定義    # 既に関数が定義されている場合は上書きしない    dounfunction=1    compadd() {      local words      local matches      local pat      local opts_array opts_assoc      local opt_p opt_s opt_D      local D_array D_array_tmp      #local orig_param      #orig_param=( "$@" )      zparseopts -D -E -a opts_array -A opts_assoc P+: S+: p+:=opt_p s+:=opt_s i+: I+: a k d+: l o J+: V+: 1 2 X+: x+: q r+: R+: f e W+: F+: Q M+: n U O+: A+: D+:=opt_D C E      if (( ${+opts_assoc[-k]} || ${+opts_assoc[-d]} || ${+opts_assoc[-U]} || ${+opts_assoc[-O]} || ${+opts_assoc[-A]} )); then	# 未対応のオプションがあれば中断する(他にも未確認のオプションはあるが)。現状は _path_files(ファイル名補完)のみ対応	# _complete と併用することを想定している	return 1	# 未対応のオプションがあればオリジナルの compadd を呼ぶコード	# この場合は _matcher についての考慮が必要	#builtin compadd "$orig_param[@]"	#return      fi      [[ $1 == (-|--) ]] && shift      opts_array+=( "$opt_p[@]" "$opt_s[@]" )      # 引数で渡された変数名と local変数の名前が重複するとまずい気がする      (( $#opt_D )) && eval "D_array=( \"\$$opt_D[2][@]\" )"      if (( ${+opts_assoc[-a]} )); then	eval "words=( \$$1 )"      else	words=( "$@" )      fi      if [[ $PREFIX != $opt_p[2]* || $SUFFIX != *$opt_s[2] ]]; then	# f/b -> foo/bar の補完でここにくる	# 未対応のケースの為、中断する	return 1      fi      # 入力パターン中に記号がある場合のことは考えてない      pat=( "${(s.:.)PREFIX#$opt_p[2]}" "${(s.:.)SUFFIX%$opt_s[2]}" )      local i      for (( i=1; i<=${#pat}; i++ )); do	_call_migemo "$pat[i]"	pat[i]="(${(Q)REPLY})"      done      pat="${(j:*:)pat}"	# egrep pattern を globbing pattern として扱う      (( $+matching_result_pat_id[$pat] )) || (( matching_result_pat_id[$pat] = $#matching_result_pat_id ))      local pat_id=$matching_result_pat_id[$pat]      local result_key      matches=()      D_array_tmp=()      for (( i=1; i<=${#words}; i++ )); do	result_key=$pat_id:$words[i]	if (( ! $+matching_result[$result_key] )); then	  [[ $words[i] == $~pat ]]	  (( matching_result[$result_key] = ! $? ))	fi	if (( matching_result[$result_key] )); then	  matches+=$words[i]	  (( $#opt_D )) && D_array_tmp+=$D_array[i]	fi      done      if (( $#opt_D )); then	# "$opt_D[2]" と local変数の名前が重複するとまずい気がする	set -A "$opt_D[2]" "$D_array_tmp[@]"      else	builtin compadd "$opts_array[@]" -U -a matches      fi    }  fi  _complete && ret=0} always {  [[ -n $dounfunction ]] && (( $+functions[compadd] )) && unfunction compadd}return ret