summaryrefslogtreecommitdiff
path: root/.local/src/blesh/lib/core-complete.sh
diff options
context:
space:
mode:
authorSaumit Dinesan <justsaumit@protonmail.com>2022-09-05 03:26:33 +0530
committerSaumit Dinesan <justsaumit@protonmail.com>2022-09-05 03:26:33 +0530
commit4a94495f747fef1b32bb8ea3aa8adbe81314795a (patch)
tree8471f4c33dfdc6cdc9136821682d5fd5f671ee47 /.local/src/blesh/lib/core-complete.sh
parente96cda8f3d313e3e95b5d5e9c9a0ccce0f81960f (diff)
spring cleaning 0.3
Diffstat (limited to '.local/src/blesh/lib/core-complete.sh')
-rw-r--r--.local/src/blesh/lib/core-complete.sh6327
1 files changed, 0 insertions, 6327 deletions
diff --git a/.local/src/blesh/lib/core-complete.sh b/.local/src/blesh/lib/core-complete.sh
deleted file mode 100644
index 9d7c4c1..0000000
--- a/.local/src/blesh/lib/core-complete.sh
+++ /dev/null
@@ -1,6327 +0,0 @@
-# this script is a part of blesh (https://github.com/akinomyoga/ble.sh) under BSD-3-Clause license
-ble/util/import "$_ble_base/lib/core-syntax.sh"
-function ble/complete/string#search-longest-suffix-in {
- local needle=$1 haystack=$2
- local l=0 u=${#needle}
- while ((l<u)); do
- local m=$(((l+u)/2))
- if [[ $haystack == *"${needle:m}"* ]]; then
- u=$m
- else
- l=$((m+1))
- fi
- done
- ret=${needle:l}
-}
-function ble/complete/string#common-suffix-prefix {
- local lhs=$1 rhs=$2
- if ((${#lhs}<${#rhs})); then
- local i n=${#lhs}
- for ((i=0;i<n;i++)); do
- ret=${lhs:i}
- [[ $rhs == "$ret"* ]] && return 0
- done
- ret=
- else
- local j m=${#rhs}
- for ((j=m;j>0;j--)); do
- ret=${rhs::j}
- [[ $lhs == *"$ret" ]] && return 0
- done
- ret=
- fi
-}
-function ble/complete/get-wordbreaks {
- wordbreaks=$_ble_term_IFS$COMP_WORDBREAKS
- [[ $wordbreaks == *'('* ]] && wordbreaks=${wordbreaks//['()']}'()'
- [[ $wordbreaks == *']'* ]] && wordbreaks=']'${wordbreaks//']'}
- [[ $wordbreaks == *'-'* ]] && wordbreaks=${wordbreaks//'-'}'-'
-}
-_ble_complete_menu_items=()
-_ble_complete_menu_class=
-_ble_complete_menu_param=
-_ble_complete_menu_version=
-_ble_complete_menu_page_style=
-_ble_complete_menu_ipage=
-_ble_complete_menu_offset=
-_ble_complete_menu_icons=()
-_ble_complete_menu_info_data=()
-_ble_complete_menu_selected=-1
-function ble/complete/menu#check-cancel {
- ((menu_iloop++%menu_interval==0)) &&
- [[ :$comp_type: != *:sync:* ]] &&
- ble/decode/has-input
-}
-_ble_complete_menu_style_measure=()
-_ble_complete_menu_style_icons=()
-_ble_complete_menu_style_pages=()
-function ble/complete/menu#render-item {
- if ble/is-function "$menu_class"/render-item; then
- "$menu_class"/render-item "$@"
- return "$?"
- fi
- local item=$1 opts=$2
- local sgr0=$_ble_term_sgr0 sgr1=$_ble_term_rev
- [[ :$opts: == *:selected:* ]] && local sgr0=$sgr1 sgr1=$sgr0
- ble/canvas/trace-text "$item" nonewline:external-sgr
- ret=$sgr0$ret$_ble_term_sgr0
-}
-function ble/complete/menu-style:align/construct/.measure-candidates-in-page {
- local max_wcell=$bleopt_menu_align_max; ((max_wcell>cols&&(max_wcell=cols)))
- ((wcell=bleopt_menu_align_min,wcell<2&&(wcell=2)))
- local ncell=0 index=$begin
- local item ret esc1 w
- for item in "${menu_items[@]:begin}"; do
- ble/complete/menu#check-cancel && return 148
- local wcell_old=$wcell
- local w=${_ble_complete_menu_style_measure[index]%%:*}
- if [[ ! $w ]]; then
- local x=0 y=0
- ble/complete/menu#render-item "$item"; esc1=$ret
- local w=$((y*cols+x))
- _ble_complete_menu_style_measure[index]=$w:${#item}:$item$esc1
- fi
- local wcell_request=$((w++,w<=max_wcell?w:max_wcell))
- ((wcell<wcell_request)) && wcell=$wcell_request
- local line_ncell=$((cols/wcell))
- local cand_ncell=$(((w+wcell-1)/wcell))
- if [[ $menu_style == align-nowrap ]]; then
- local x1=$((ncell%line_ncell*wcell))
- local ncell_eol=$(((ncell/line_ncell+1)*line_ncell))
- if ((x1>0&&x1+w>=cols)); then
- ((ncell=ncell_eol+cand_ncell))
- elif ((x1+w<cols)); then
- ((ncell+=cand_ncell))
- ((ncell>ncell_eol&&(ncell=ncell_eol)))
- else
- ((ncell+=cand_ncell))
- fi
- else
- ((ncell+=cand_ncell))
- fi
- local max_ncell=$((line_ncell*lines))
- ((index&&ncell>max_ncell)) && { wcell=$wcell_old; break; }
- ((index++))
- done
- end=$index
-}
-function ble/complete/menu-style:align/construct-page {
- x=0 y=0 esc=
- local wcell=2
- ble/complete/menu-style:align/construct/.measure-candidates-in-page
- (($?==148)) && return 148
- local ncell=$((cols/wcell))
- local index=$begin entry
- for entry in "${_ble_complete_menu_style_measure[@]:begin:end-begin}"; do
- ble/complete/menu#check-cancel && return 148
- local w=${entry%%:*}; entry=${entry#*:}
- local s=${entry%%:*}; entry=${entry#*:}
- local item=${entry::s} esc1=${entry:s}
- local x0=$x y0=$y
- if ((x==0||x+w<cols)); then
- ((x+=w%cols,y+=w/cols))
- ((y>=lines&&(x=x0,y=y0,1))) && break
- else
- if [[ $menu_style == align-nowrap ]]; then
- ((y+1>=lines)) && break
- esc=$esc$'\n'
- ((x0=x=0,y0=++y))
- ((x=w%cols,y+=w/cols))
- ((y>=lines&&(x=x0,y=y0,1))) && break
- else
- ble/complete/menu#render-item "$item" ||
- ((begin==index)) || # [Note: 少なくとも1個ははみ出ても表示する]
- { x=$x0 y=$y0; break; }; esc1=$ret
- fi
- fi
- _ble_complete_menu_style_icons[index]=$x0,$y0,$x,$y,${#item},${#esc1}:$item$esc1
- esc=$esc$esc1
- if ((++index<end)); then
- local icell=$((x==0?0:(x+wcell)/wcell))
- if ((icell<ncell)); then
- local pad=$((icell*wcell-x))
- ble/string#reserve-prototype "$pad"
- esc=$esc${_ble_string_prototype::pad}
- ((x=icell*wcell))
- else
- ((y+1>=lines)) && break
- esc=$esc$'\n'
- ((x=0,++y))
- fi
- fi
- done
- end=$index
-}
-function ble/complete/menu-style:align-nowrap/construct-page {
- ble/complete/menu-style:align/construct-page "$@"
-}
-function ble/complete/menu-style:dense/construct-page {
- x=0 y=0 esc=
- local item index=$begin N=${#menu_items[@]}
- for item in "${menu_items[@]:begin}"; do
- ble/complete/menu#check-cancel && return 148
- local x0=$x y0=$y esc1
- ble/complete/menu#render-item "$item" ||
- ((index==begin)) ||
- { x=$x0 y=$y0; break; }; esc1=$ret
- if [[ $menu_style == dense-nowrap ]]; then
- if ((y>y0&&x>0||y>y0+1)); then
- ((++y0>=lines)) && break
- esc=$esc$'\n'
- ((y=y0,x=x0=0))
- ble/complete/menu#render-item "$item" ||
- ((begin==index)) ||
- { x=$x0 y=$y0; break; }; esc1=$ret
- fi
- fi
- _ble_complete_menu_style_icons[index]=$x0,$y0,$x,$y,${#item},${#esc1}:$item$esc1
- esc=$esc$esc1
- if ((++index<N)); then
- if [[ $menu_style == dense-nowrap ]] && ((x==0)); then
- : skip
- elif ((x+1<cols)); then
- esc=$esc' '
- ((x++))
- else
- ((y+1>=lines)) && break
- esc=$esc$'\n'
- ((x=0,++y))
- fi
- fi
- done
- end=$index
-}
-function ble/complete/menu-style:dense-nowrap/construct-page {
- ble/complete/menu-style:dense/construct-page "$@"
-}
-function ble/complete/menu-style:linewise/construct-page {
- local opts=$1 ret
- local max_icon_width=$((cols-1))
- local prefix_format=$bleopt_menu_linewise_prefix prefix_width=0
- if [[ $prefix_format ]]; then
- local prefix1
- ble/util/sprintf prefix1 "$prefix_format" ${#menu_items[@]}
- local x1 y1 x2 y2
- LINES=1 COLUMNS=$max_icon_width x=0 y=0 ble/canvas/trace "$prefix1" truncate:measure-bbox
- if ((x2<=max_icon_width/2)); then
- prefix_width=$x2
- ble/string#reserve-prototype "$prefix_width"
- fi
- fi
- local item x0 y0 esc1 index=$begin
- end=$begin x=0 y=0 esc=
- for item in "${menu_items[@]:begin:lines}"; do
- ble/complete/menu#check-cancel && return 148
- if ((prefix_width)); then
- local prefix1; ble/util/sprintf prefix1 "$prefix_format" $((index+1))
- LINES=1 COLUMNS=$max_icon_width y=0 ble/canvas/trace "$prefix1" truncate:relative:measure-bbox; esc1=$ret
- if ((x<prefix_width)); then
- x=$prefix_width
- esc=$esc${_ble_string_prototype::prefix_width-x}$esc1
- else
- esc=$esc$esc1
- fi
- fi
- ((x0=x,y0=y))
- lines=1 cols=$max_icon_width y=0 ble/complete/menu#render-item "$item"; esc1=$ret
- _ble_complete_menu_style_icons[index]=$x0,$y0,$x,$y,${#item},${#esc1}:$item$esc1
- ((index++))
- esc=$esc$esc1
- ((y+1>=lines)) && break
- ((x=0,++y))
- esc=$esc$'\n'
- done
- end=$index
-}
-function ble/complete/menu-style:linewise/guess {
- ((ipage=scroll/lines,
- begin=ipage*lines,
- end=begin))
-}
-_ble_complete_menu_desc_pageheight=()
-function ble/complete/menu-style:desc/construct-page {
- local opts=$1 ret
- local opt_raw=; [[ $menu_style != desc-text ]] && opt_raw=1
- end=$begin esc= x=0 y=0
- local colsep=' | '
- local desc_sgr0=$'\e[m'
- ble/color/face2sgr-ansi syntax_quoted; local desc_sgrq=$ret
- ble/color/face2sgr-ansi syntax_delimiter; local desc_sgrt=$ret
- local ncolumn=1 nline=$lines
- local nrest_item=$((${#menu_items[@]}-begin))
- if [[ $bleopt_menu_desc_multicolumn_width ]]; then
- ncolumn=$((cols/bleopt_menu_desc_multicolumn_width))
- if ((ncolumn<1)); then
- ncolumn=1
- elif ((ncolumn>nrest_item)); then
- ncolumn=$nrest_item
- fi
- fi
- ((nline=(${#menu_items[@]}-begin+ncolumn-1)/ncolumn,
- nline>lines&&(nline=lines)))
- local ncolumn_max=$(((nrest_item+nline-1)/nline))
- ((ncolumn>ncolumn_max&&(ncolumn=ncolumn_max)))
- local available_width=$cols
- case $_ble_term_TERM in
- (screen:*|tmux:*|kitty:*|contra:*) ;;
- (*) ((available_width--)) ;;
- esac
- local wcolumn=$(((available_width-${#colsep}*(ncolumn-1))/ncolumn))
- local wcand_limit=$(((wcolumn+1)*2/3))
- ((wcand_limit<10&&(wcand_limit=wcolumn)))
- local -a DRAW_BUFF=()
- local index=$begin icolumn ymax=0
- for ((icolumn=0;icolumn<ncolumn;icolumn++)); do
- local measure; measure=()
- local pack w esc1 max_width=0
- for pack in "${menu_items[@]:index:nline}"; do
- ble/complete/menu#check-cancel && return 148
- x=0 y=0
- lines=1 cols=$wcand_limit ble/complete/menu#render-item "$pack"; esc1=$ret
- ((w=y*wcolumn+x,w>max_width&&(max_width=w)))
- ble/array#push measure "$w:${#pack}:$pack$esc1"
- done
- local cand_width=$max_width
- local desc_x=$((cand_width+1)); ((desc_x>wcolumn&&(desc_x=wcolumn)))
- local desc_prefix=; ((wcolumn-desc_x>30)) && desc_prefix=': '
- local xcolumn=$((icolumn*(wcolumn+${#colsep})))
- x=0 y=0
- local entry w s pack esc1 x0 y0 pad
- for entry in "${measure[@]}"; do
- ble/complete/menu#check-cancel && return 148
- w=${entry%%:*} entry=${entry#*:}
- s=${entry%%:*} entry=${entry#*:}
- pack=${entry::s} esc1=${entry:s}
- ((x0=x,y0=y,x+=w))
- _ble_complete_menu_style_icons[index]=$((xcolumn+x0)),$y0,$((xcolumn+x)),$y,${#pack},${#esc1},"0 0 $wcand_limit 1":$pack$esc1
- ((index++))
- ble/canvas/put.draw "$esc1"
- ble/canvas/put-spaces.draw $((pad=desc_x-x))
- ble/canvas/put.draw "$desc_prefix"
- ((x+=pad+${#desc_prefix}))
- local desc=$desc_sgrt'(no description)'$desc_sgr0
- ble/function#try "$menu_class"/get-desc "$pack"
- if [[ $opt_raw ]]; then
- y=0 g=0 lc=0 lg=0 LINES=1 COLUMNS=$wcolumn ble/canvas/trace.draw "$desc" truncate:relative:ellipsis
- else
- y=0 lines=1 cols=$wcolumn ble/canvas/trace-text "$desc" nonewline
- ble/canvas/put.draw "$ret"
- fi
- ble/canvas/put.draw "$_ble_term_sgr0"
- ((y+1>=nline)) && break
- ble/canvas/put-move.draw $((-x)) 1
- ((x=0,++y))
- done
- ((y>ymax)) && ymax=$y
- if ((icolumn+1<ncolumn)); then
- ble/canvas/put-move.draw $((wcolumn-x)) $((-y))
- for ((y=0;y<=ymax;y++)); do
- ble/canvas/put.draw "$colsep"
- if ((y<ymax)); then
- ble/canvas/put-move.draw -${#colsep} 1
- else
- ble/canvas/put-move-y.draw $((-y))
- fi
- done
- else
- ((y<ymax)) && ble/canvas/put-move-y.draw $((ymax-y))
- ((x+=xcolumn,y=ymax))
- fi
- done
- _ble_complete_menu_desc_pageheight[ipage]=$nline
- end=$index
- ble/canvas/sflush.draw -v esc
-}
-function ble/complete/menu-style:desc/guess {
- local ncolumn=1
- if [[ $bleopt_menu_desc_multicolumn_width ]]; then
- ncolumn=$((cols/bleopt_menu_desc_multicolumn_width))
- ((ncolumn<1)) && ncolumn=1
- fi
- local nitem_per_page=$((ncolumn*lines))
- ((ipage=scroll/nitem_per_page,
- begin=ipage*nitem_per_page,
- end=begin))
-}
-function ble/complete/menu-style:desc/locate {
- local type=$1 osel=$2
- local ipage=$_ble_complete_menu_ipage
- local nline=${_ble_complete_menu_desc_pageheight[ipage]:-1}
- case $type in
- (right) ((ret=osel+nline)) ;;
- (left) ((ret=osel-nline)) ;;
- (down) ((ret=osel+1)) ;;
- (up) ((ret=osel-1)) ;;
- (*) return 1 ;;
- esac
- local beg=$_ble_complete_menu_offset
- local end=$((beg+${#_ble_complete_menu_icons[@]}))
- if ((ret<beg)); then
- ((ret=beg-1))
- elif ((ret>end)); then
- ((ret=end))
- fi
- return 0
-}
-function ble/complete/menu-style:desc-text/construct-page { ble/complete/menu-style:desc/construct-page "$@"; }
-function ble/complete/menu-style:desc-text/guess { ble/complete/menu-style:desc/guess; }
-function ble/complete/menu-style:desc-text/locate { ble/complete/menu-style:desc/locate "$@"; }
-function ble/complete/menu-style:desc-raw/construct-page { ble/complete/menu-style:desc/construct-page "$@"; }
-function ble/complete/menu-style:desc-raw/guess { ble/complete/menu-style:desc/guess; }
-function ble/complete/menu-style:desc-raw/locate { ble/complete/menu-style:desc/locate "$@"; }
-function ble/complete/menu#construct/.initialize-size {
- ble/edit/info/.initialize-size
- local maxlines=$((bleopt_complete_menu_maxlines))
- ((maxlines>0&&lines>maxlines)) && lines=$maxlines
-}
-function ble/complete/menu#construct {
- local menu_opts=$1
- local menu_iloop=0
- local menu_interval=$bleopt_complete_polling_cycle
- local cols lines
- ble/complete/menu#construct/.initialize-size
- local nitem=${#menu_items[@]}
- local version=$nitem:$lines:$cols
- if ((nitem==0)); then
- _ble_complete_menu_version=$version
- _ble_complete_menu_items=()
- _ble_complete_menu_page_style=
- _ble_complete_menu_ipage=0
- _ble_complete_menu_offset=0
- _ble_complete_menu_icons=()
- _ble_complete_menu_info_data=(ansi $'\e[38;5;242m(no items)\e[m')
- _ble_complete_menu_selected=-1
- return 0
- fi
- local scroll=0 rex=':scroll=([0-9]+):' use_cache=
- if [[ :$menu_opts: =~ $rex ]]; then
- scroll=${BASH_REMATCH[1]}
- ((nitem&&(scroll%=nitem)))
- [[ $_ble_complete_menu_version == $version ]] && use_cache=1
- fi
- if [[ ! $use_cache ]]; then
- _ble_complete_menu_style_measure=()
- _ble_complete_menu_style_icons=()
- _ble_complete_menu_style_pages=()
- fi
- local begin=0 end=0 ipage=0 x y esc
- ble/function#try ble/complete/menu-style:"$menu_style"/guess
- while ((end<nitem)); do
- ((scroll<begin)) && return 1
- local page_data=${_ble_complete_menu_style_pages[ipage]}
- if [[ $page_data ]]; then
- local fields; ble/string#split fields , "${page_data%%:*}"
- begin=${fields[0]} end=${fields[1]}
- if ((begin<=scroll&&scroll<end)); then
- x=${fields[2]} y=${fields[3]} esc=${page_data#*:}
- break
- fi
- else
- ble/complete/menu-style:"$menu_style"/construct-page "$menu_opts" || return "$?"
- _ble_complete_menu_style_pages[ipage]=$begin,$end,$x,$y:$esc
- ((begin<=scroll&&scroll<end)) && break
- fi
- begin=$end
- ((ipage++))
- done
- _ble_complete_menu_version=$version
- _ble_complete_menu_items=("${menu_items[@]}")
- _ble_complete_menu_class=$menu_class
- _ble_complete_menu_param=$menu_param
- _ble_complete_menu_page_style=$menu_style
- _ble_complete_menu_ipage=$ipage
- _ble_complete_menu_offset=$begin
- _ble_complete_menu_icons=("${_ble_complete_menu_style_icons[@]:begin:end-begin}")
- _ble_complete_menu_info_data=(store "$x" "$y" "$esc")
- _ble_complete_menu_selected=-1
- return 0
-}
-function ble/complete/menu#show {
- ble/edit/info/immediate-show "${_ble_complete_menu_info_data[@]}"
-}
-function ble/complete/menu#clear {
- ble/edit/info/default
-}
-function ble/complete/menu#select {
- local menu_class=$_ble_complete_menu_class
- local menu_param=$_ble_complete_menu_param
- local osel=$_ble_complete_menu_selected nsel=$1 opts=$2
- local ncand=${#_ble_complete_menu_items[@]}
- ((0<=osel&&osel<ncand)) || osel=-1
- ((0<=nsel&&nsel<ncand)) || nsel=-1
- ((osel==nsel)) && return 0
- local infox infoy
- ble/canvas/panel#get-origin "$_ble_edit_info_panel" --prefix=info
- local visible_beg=$_ble_complete_menu_offset
- local visible_end=$((visible_beg+${#_ble_complete_menu_icons[@]}))
- if ((nsel>=0&&!(visible_beg<=nsel&&nsel<visible_end))); then
- ble/complete/menu/show filter:load-filtered-data:scroll="$nsel"; local ext=$?
- ((ext)) && return "$ext"
- if [[ $_ble_complete_menu_ipage ]]; then
- local ipage=$_ble_complete_menu_ipage
- ble/term/visible-bell "menu: Page $((ipage+1))" persistent
- else
- ble/term/visible-bell "menu: Offset $_ble_complete_menu_offset/$ncand" persistent
- fi
- visible_beg=$_ble_complete_menu_offset
- visible_end=$((visible_beg+${#_ble_complete_menu_icons[@]}))
- ((visible_end<=nsel&&(nsel=visible_end-1)))
- ((nsel<=visible_beg&&(nsel=visible_beg)))
- ((visible_beg<=osel&&osel<visible_end)) || osel=-1
- fi
- local -a DRAW_BUFF=()
- local ret; ble/canvas/panel/save-position; local pos0=$ret
- if ((osel>=0)); then
- local entry=${_ble_complete_menu_icons[osel-visible_beg]}
- local fields text=${entry#*:}
- ble/string#split fields , "${entry%%:*}"
- if ((fields[3]<_ble_canvas_panel_height[_ble_edit_info_panel])); then
- ble/canvas/panel#goto.draw "$_ble_edit_info_panel" "${fields[@]::2}"
- ble/canvas/put.draw "${text:fields[4]}"
- _ble_canvas_x=${fields[2]} _ble_canvas_y=$((infoy+fields[3]))
- fi
- fi
- local value=
- if ((nsel>=0)); then
- [[ :$opts: == *:goto-page-top:* ]] && nsel=$visible_beg
- local entry=${_ble_complete_menu_icons[nsel-visible_beg]}
- local fields text=${entry#*:}
- ble/string#split fields , "${entry%%:*}"
- local x=${fields[0]} y=${fields[1]}
- local item=${text::fields[4]}
- local ret
- if [[ ${fields[6]} ]]; then
- local box cols lines
- ble/string#split-words box "${fields[6]}"
- x=${box[0]} y=${box[1]} cols=${box[2]} lines=${box[3]}
- ble/complete/menu#render-item "$item" selected
- ((x+=fields[0]-box[0]))
- ((y+=fields[1]-box[1]))
- else
- local cols lines
- ble/complete/menu#construct/.initialize-size
- ble/complete/menu#render-item "$item" selected
- fi
- if ((y<_ble_canvas_panel_height[_ble_edit_info_panel])); then
- ble/canvas/panel#goto.draw "$_ble_edit_info_panel" "${fields[@]::2}"
- ble/canvas/put.draw "$ret"
- _ble_canvas_x=$x _ble_canvas_y=$((infoy+y))
- fi
- _ble_complete_menu_selected=$nsel
- else
- _ble_complete_menu_selected=-1
- value=$_ble_complete_menu_original
- fi
- ble/canvas/panel/load-position.draw "$pos0"
- ble/canvas/bflush.draw
- ble/function#try "$menu_class"/onselect "$nsel" "$osel"
- return 0
-}
-function ble/widget/menu/forward {
- local opts=$1
- local nsel=$((_ble_complete_menu_selected+1))
- local ncand=${#_ble_complete_menu_items[@]}
- if ((nsel>=ncand)); then
- if [[ :$opts: == *:cyclic:* ]] && ((ncand>=2)); then
- nsel=0
- else
- ble/widget/.bell "menu: no more candidates"
- return 1
- fi
- fi
- ble/complete/menu#select "$nsel"
-}
-function ble/widget/menu/backward {
- local opts=$1
- local nsel=$((_ble_complete_menu_selected-1))
- if ((nsel<0)); then
- local ncand=${#_ble_complete_menu_items[@]}
- if [[ :$opts: == *:cyclic:* ]] && ((ncand>=2)); then
- ((nsel=ncand-1))
- else
- ble/widget/.bell "menu: no more candidates"
- return 1
- fi
- fi
- ble/complete/menu#select "$nsel"
-}
-function ble/widget/menu/forward-column {
- local osel=$((_ble_complete_menu_selected))
- if local ret; ble/function#try ble/complete/menu-style:"$_ble_complete_menu_page_style"/locate right "$osel"; then
- local nsel=$ret ncand=${#_ble_complete_menu_items[@]}
- if ((0<=nsel&&nsel<ncand&&nsel!=osel)); then
- ble/complete/menu#select "$nsel"
- else
- ble/widget/.bell "menu: no more candidates"
- fi
- else
- ble/widget/menu/forward
- fi
-}
-function ble/widget/menu/backward-column {
- local osel=$((_ble_complete_menu_selected))
- if local ret; ble/function#try ble/complete/menu-style:"$_ble_complete_menu_page_style"/locate left "$osel"; then
- local nsel=$ret ncand=${#_ble_complete_menu_items[@]}
- if ((0<=nsel&&nsel<ncand&&nsel!=osel)); then
- ble/complete/menu#select "$nsel"
- else
- ble/widget/.bell "menu: no more candidates"
- fi
- else
- ble/widget/menu/backward
- fi
-}
-_ble_complete_menu_lastcolumn=
-function ble/widget/menu/.check-last-column {
- if [[ $_ble_complete_menu_lastcolumn ]]; then
- local lastwidget=${LASTWIDGET%%' '*}
- if [[ $lastwidget == ble/widget/menu/forward-line ||
- $lastwidget == ble/widget/menu/backward-line ]]
- then
- ox=$_ble_complete_menu_lastcolumn
- return 0
- fi
- fi
- _ble_complete_menu_lastcolumn=$ox
-}
-function ble/widget/menu/.goto-column {
- local column=$1
- local offset=$_ble_complete_menu_offset
- local osel=$_ble_complete_menu_selected
- ((osel>=0)) || return 1
- local entry=${_ble_complete_menu_icons[osel-offset]}
- local fields; ble/string#split fields , "${entry%%:*}"
- local ox=${fields[0]} oy=${fields[1]}
- local nsel=-1
- if ((ox<column)); then
- nsel=$osel
- for entry in "${_ble_complete_menu_icons[@]:osel+1-offset}"; do
- ble/string#split fields , "${entry%%:*}"
- local x=${fields[0]} y=${fields[1]}
- ((y==oy&&x<=column)) || break
- ((nsel++))
- done
- elif ((ox>column)); then
- local i=$osel
- while ((--i>=offset)); do
- entry=${_ble_complete_menu_icons[i-offset]}
- ble/string#split fields , "${entry%%:*}"
- local x=${fields[0]} y=${fields[1]}
- ((y<oy||x<=column&&(nsel=i,1))) && break
- done
- fi
- ((nsel>=0&&nsel!=osel)) &&
- ble/complete/menu#select "$nsel"
-}
-function ble/widget/menu/forward-line {
- local offset=$_ble_complete_menu_offset
- local osel=$_ble_complete_menu_selected
- ((osel>=0)) || return 1
- local nsel=-1 goto_column=
- if local ret; ble/function#try ble/complete/menu-style:"$_ble_complete_menu_page_style"/locate down "$osel"; then
- nsel=$ret
- else
- local entry=${_ble_complete_menu_icons[osel-offset]}
- local fields; ble/string#split fields , "${entry%%:*}"
- local ox=${fields[0]} oy=${fields[1]}
- ble/widget/menu/.check-last-column
- local i=$osel nsel=-1 is_next_page=
- for entry in "${_ble_complete_menu_icons[@]:osel+1-offset}"; do
- ble/string#split fields , "${entry%%:*}"
- local x=${fields[0]} y=${fields[1]}
- ((y<=oy||y==oy+1&&x<=ox||nsel<0)) || break
- ((++i,y>oy&&(nsel=i)))
- done
- ((nsel<0&&(is_next_page=1,nsel=offset+${#_ble_complete_menu_icons[@]})))
- ((is_next_page)) && goto_column=$ox
- fi
- local ncand=${#_ble_complete_menu_items[@]}
- if ((0<=nsel&&nsel<ncand)); then
- ble/complete/menu#select "$nsel"
- [[ $goto_column ]] && ble/widget/menu/.goto-column "$goto_column"
- return 0
- else
- ble/widget/.bell 'menu: no more candidates'
- return 1
- fi
-}
-function ble/widget/menu/backward-line {
- local offset=$_ble_complete_menu_offset
- local osel=$_ble_complete_menu_selected
- ((osel>=0)) || return 1
- local nsel=-1 goto_column=
- if local ret; ble/function#try ble/complete/menu-style:"$_ble_complete_menu_page_style"/locate up "$osel"; then
- nsel=$ret
- else
- local entry=${_ble_complete_menu_icons[osel-offset]}
- local fields; ble/string#split fields , "${entry%%:*}"
- local ox=${fields[0]} oy=${fields[1]}
- ble/widget/menu/.check-last-column
- local nsel=$osel
- while ((--nsel>=offset)); do
- entry=${_ble_complete_menu_icons[nsel-offset]}
- ble/string#split fields , "${entry%%:*}"
- local x=${fields[0]} y=${fields[1]}
- ((y<oy-1||y==oy-1&&x<=ox)) && break
- done
- ((0<=nsel&&nsel<offset)) && goto_column=$ox
- fi
- local ncand=${#_ble_complete_menu_items[@]}
- if ((0<=nsel&&nsel<ncand)); then
- ble/complete/menu#select "$nsel"
- [[ $goto_column ]] && ble/widget/menu/.goto-column "$goto_column"
- else
- ble/widget/.bell 'menu: no more candidates'
- return 1
- fi
-}
-function ble/widget/menu/backward-page {
- if ((_ble_complete_menu_offset>0)); then
- ble/complete/menu#select $((_ble_complete_menu_offset-1)) goto-page-top
- else
- ble/widget/.bell "menu: this is the first page."
- return 1
- fi
-}
-function ble/widget/menu/forward-page {
- local next=$((_ble_complete_menu_offset+${#_ble_complete_menu_icons[@]}))
- if ((next<${#_ble_complete_menu_items[@]})); then
- ble/complete/menu#select "$next"
- else
- ble/widget/.bell "menu: this is the last page."
- return 1
- fi
-}
-function ble/widget/menu/beginning-of-page {
- ble/complete/menu#select "$_ble_complete_menu_offset"
-}
-function ble/widget/menu/end-of-page {
- local nicon=${#_ble_complete_menu_icons[@]}
- ((nicon)) && ble/complete/menu#select $((_ble_complete_menu_offset+nicon-1))
-}
-function ble/widget/menu/cancel {
- ble/decode/keymap/pop
- ble/complete/menu#clear
- "$_ble_complete_menu_class"/oncancel
-}
-function ble/widget/menu/accept {
- ble/decode/keymap/pop
- ble/complete/menu#clear
- local nsel=$_ble_complete_menu_selected
- local hook=$_ble_complete_menu_accept_hook
- _ble_complete_menu_accept_hook=
- if ((nsel>=0)); then
- "$_ble_complete_menu_class"/onaccept "$nsel" "${_ble_complete_menu_items[nsel]}"
- else
- "$_ble_complete_menu_class"/onaccept "$nsel"
- fi
-}
-function ble-decode/keymap:menu/define {
- ble-bind -f __default__ 'bell'
- ble-bind -f __line_limit__ nop
- ble-bind -f C-m 'menu/accept'
- ble-bind -f RET 'menu/accept'
- ble-bind -f C-g 'menu/cancel'
- ble-bind -f 'C-x C-g' 'menu/cancel'
- ble-bind -f 'C-M-g' 'menu/cancel'
- ble-bind -f C-f 'menu/forward-column'
- ble-bind -f right 'menu/forward-column'
- ble-bind -f C-i 'menu/forward cyclic'
- ble-bind -f TAB 'menu/forward cyclic'
- ble-bind -f C-b 'menu/backward-column'
- ble-bind -f left 'menu/backward-column'
- ble-bind -f C-S-i 'menu/backward cyclic'
- ble-bind -f S-TAB 'menu/backward cyclic'
- ble-bind -f C-n 'menu/forward-line'
- ble-bind -f down 'menu/forward-line'
- ble-bind -f C-p 'menu/backward-line'
- ble-bind -f up 'menu/backward-line'
- ble-bind -f prior 'menu/backward-page'
- ble-bind -f next 'menu/forward-page'
- ble-bind -f home 'menu/beginning-of-page'
- ble-bind -f end 'menu/end-of-page'
-}
-function ble/complete/menu.class/onaccept {
- local hook=$_ble_complete_menu_accept_hook
- _ble_complete_menu_accept_hook=
- "$hook" "$@"
-}
-function ble/complete/menu.class/oncancel {
- local hook=$_ble_complete_menu_cancel_hook
- _ble_complete_menu_cancel_hook=
- "$hook" "$@"
-}
-function ble/complete/menu#start {
- _ble_complete_menu_accept_hook=$1; shift
- _ble_complete_menu_cancel_hook=
- local menu_style=linewise
- local menu_items; menu_items=("$@")
- local menu_class=ble/complete/menu.class menu_param=
- ble/complete/menu#construct sync || return "$?"
- ble/complete/menu#show
- ble/complete/menu#select 0
- ble/decode/keymap/push menu
- return 147
-}
-function ble/complete/check-cancel {
- [[ :$comp_type: != *:sync:* ]] && ble/decode/has-input
-}
-function ble/complete/string#escape-for-completion-context {
- local str=$1 escape_flags=$2
- case $comps_flags in
- (*S*) ble/string#escape-for-bash-single-quote "$str" ;;
- (*E*) ble/string#escape-for-bash-escape-string "$str" ;;
- (*[DI]*) ble/string#escape-for-bash-double-quote "$str" ;;
- (*)
- if [[ $comps_fixed ]]; then
- ble/string#escape-for-bash-specialchars "$str" "b$escape_flags"
- else
- ble/string#escape-for-bash-specialchars "$str" "$escape_flags"
- fi ;;
- esac
-}
-function ble/complete/action/complete.addtail {
- suffix=$suffix$1
-}
-function ble/complete/action/complete.mark-directory {
- [[ :$comp_type: == *:markdir:* && $CAND != */ ]] &&
- [[ ! -h $CAND || ( $insert == "$COMPS" || :$comp_type: == *:marksymdir:* ) ]] &&
- ble/complete/action/complete.addtail /
-}
-function ble/complete/action/complete.close-quotation {
- case $comps_flags in
- (*[SE]*) ble/complete/action/complete.addtail \' ;;
- (*[DI]*) ble/complete/action/complete.addtail \" ;;
- esac
-}
-_ble_complete_quote_insert_varnames=(
- quote_action
- quote_escape_flags
- quote_cont_cutbackslash
- quote_paramx_comps
- quote_trav_prefix
- quote_fixed_comps
- quote_fixed_compv
- quote_fixed_comps_len
- quote_fixed_compv_len)
-function ble/complete/action/quote-insert.initialize {
- quote_action=$1
- quote_escape_flags=c
- if [[ $quote_action == command ]]; then
- quote_escape_flags=
- elif [[ $quote_action == progcomp ]]; then
- [[ $comp_opts != *:filenames:* ]] &&
- quote_escape_flags=${quote_escape_flags//c}
- fi
- [[ $comps_fixed ]] && quote_escape_flags=b$quote_escape_flags
- quote_cont_cutbackslash=
- [[ $comps_flags == *B* && $COMPS == *'\' ]] &&
- quote_cont_cutbackslash=1
- quote_paramx_comps=$COMPS
- if [[ $comps_flags == *p* ]]; then
- [[ $comps_flags == *B* && $quote_paramx_comps == *'\' ]] &&
- quote_paramx_comps=${quote_paramx_comps%'\'}
- case $comps_flags in
- (*[DI]*)
- if [[ $COMPS =~ $rex_raw_paramx ]]; then
- local rematch1=${BASH_REMATCH[1]}
- quote_paramx_comps=$rematch1'${'${COMPS:${#rematch1}+1}'}'
- else
- quote_paramx_comps=$quote_paramx_comps'""'
- fi ;;
- (*)
- quote_paramx_comps=$quote_paramx_comps'\' ;;
- esac
- fi
- quote_trav_prefix=
- case $comps_flags in
- (*S*) quote_trav_prefix=\' ;;
- (*E*) quote_trav_prefix=\$\' ;;
- (*D*) quote_trav_prefix=\" ;;
- (*I*) quote_trav_prefix=\$\" ;;
- esac
- quote_fixed_comps=
- quote_fixed_compv=
- quote_fixed_comps_len=
- quote_fixed_compv_len=
- if [[ $comps_fixed ]]; then
- quote_fixed_compv=${comps_fixed#*:}
- quote_fixed_compv_len=${#quote_fixed_compv}
- quote_fixed_comps_len=${comps_fixed%%:*}
- quote_fixed_comps=${COMPS::quote_fixed_comps_len}
- fi
-}
-function ble/complete/action/quote-insert {
- if [[ ! $quote_action ]]; then
- local "${_ble_complete_quote_insert_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/action/quote-insert.initialize "${1:-plain}"
- fi
- local escape_flags=$quote_escape_flags
- if [[ $quote_action == command ]]; then
- [[ $DATA == *:noquote:* || $COMPS == "$COMPV" && ( $CAND == '[[' || $CAND == '!' ) ]] && return 0
- elif [[ $quote_action == progcomp ]]; then
- [[ $comp_opts == *:noquote:* ]] && return 0
- [[ $comp_opts == *:nospace:* && $CAND == *' ' && ! -f $CAND ]] && return 0
- [[ $CAND == '~'* && ! ( $comp_opts == *:filenames:* && -e $CAND ) ]] &&
- escape_flags=T$escape_flags
- fi
- if [[ $comps_flags == *v* && $CAND == "$COMPV"* ]]; then
- local ins ret
- ble/complete/string#escape-for-completion-context "${CAND:${#COMPV}}" "$escape_flags"; ins=$ret
- if [[ $comps_flags == *p* && $ins == [_a-zA-Z0-9]* ]]; then
- INSERT=$quote_paramx_comps$ins
- else
- [[ $quote_cont_cutbackslash ]] && ins=${ins#'\'}
- INSERT=$COMPS$ins;
- fi
- elif [[ $quote_fixed_comps && $CAND == "$quote_fixed_compv"* ]]; then
- local ret; ble/complete/string#escape-for-completion-context "${CAND:quote_fixed_compv_len}" "$escape_flags"
- INSERT=$quote_fixed_comps$quote_trav_prefix$ret
- else
- local ret; ble/complete/string#escape-for-completion-context "$CAND" "$escape_flags"
- INSERT=$quote_trav_prefix$ret
- fi
-}
-function ble/complete/action/quote-insert.batch/awk {
- local q=\'
- local -x comp_opts=$comp_opts
- local -x comps=$COMPS
- local -x compv=$COMPV
- local -x comps_flags=$comps_flags
- local -x quote_action=$quote_action
- local -x quote_escape_flags=$quote_escape_flags
- local -x quote_paramx_comps=$quote_paramx_comps
- local -x quote_cont_cutbackslash=$quote_cont_cutbackslash
- local -x quote_trav_prefix=$quote_trav_prefix
- local -x quote_fixed_comps=$quote_fixed_comps
- local -x quote_fixed_compv=$quote_fixed_compv
- "$quote_batch_awk" -v quote_batch_nulsep="$quote_batch_nulsep" -v q="$q" '
- function exists(filename) { return substr($0, 1, 1) == "1"; }
- function is_file(filename) { return substr($0, 2, 1) == "1"; }
- function initialize(_, flags, comp_opts, tmp) {
- IS_XPG4 = AWKTYPE == "xpg4";
- REP_SL = "\\";
- if (IS_XPG4) REP_SL = "\\\\";
- REP_DBL_SL = "\\\\"; # gawk, nawk
- sub(/.*/, REP_DBL_SL, tmp);
- if (tmp == "\\") REP_DBL_SL = "\\\\\\\\"; # mawk, xpg4
- Q = q "\\" q q;
- DELIM = 10;
- if (quote_batch_nulsep != "") {
- RS = "\0";
- DELIM = 0;
- }
- quote_action = ENVIRON["quote_action"];
- comps = ENVIRON["comps"];
- compv = ENVIRON["compv"];
- compv_len = length(compv);
- comps_flags = ENVIRON["comps_flags"];
- escape_type = 0;
- if (comps_flags ~ /S/)
- escape_type = 1;
- else if (comps_flags ~ /E/)
- escape_type = 2;
- else if (comps_flags ~ /[DI]/)
- escape_type = 3;
- else
- escape_type = 4;
- comps_v = (comps_flags ~ /v/);
- comps_p = (comps_flags ~ /p/);
- comp_opts = ENVIRON["comp_opts"];
- is_noquote = comp_opts ~ /:noquote:/;
- is_nospace = comp_opts ~ /:nospace:/;
- flags = ENVIRON["quote_escape_flags"];
- escape_c = (flags ~ /c/);
- escape_b = (flags ~ /b/);
- escape_tilde_always = 1;
- escape_tilde_exists = 0;
- if (quote_action == "progcomp") {
- escape_tilde_always = 0;
- escape_tilde_exists = (comp_opts ~ /:filenames:/);
- }
- quote_cont_cutbackslash = ENVIRON["quote_cont_cutbackslash"] != "";
- quote_paramx_comps = ENVIRON["quote_paramx_comps"];
- quote_trav_prefix = ENVIRON["quote_trav_prefix"];
- quote_fixed_comps = ENVIRON["quote_fixed_comps"];
- quote_fixed_compv = ENVIRON["quote_fixed_compv"];
- quote_fixed_comps_len = length(quote_fixed_comps);
- quote_fixed_compv_len = length(quote_fixed_compv);
- }
- BEGIN { initialize(); }
- function escape_for_completion_context(text) {
- if (escape_type == 1) {
- gsub(/'$q'/, Q, text);
- } else if (escape_type == 2) {
- if (text ~ /[\\'$q'\a\b\t\n\v\f\r\033]/) {
- gsub(/\\/ , REP_DBL_SL, text);
- gsub(/'$q'/, REP_SL q , text);
- gsub(/\007/, REP_SL "a", text);
- gsub(/\010/, REP_SL "b", text);
- gsub(/\011/, REP_SL "t", text);
- gsub(/\012/, REP_SL "n", text);
- gsub(/\013/, REP_SL "v", text);
- gsub(/\014/, REP_SL "f", text);
- gsub(/\015/, REP_SL "r", text);
- gsub(/\033/, REP_SL "e", text);
- }
- } else if (escape_type == 3) {
- gsub(/[\\"$`]/, "\\\\&", text); # Note: All awks behaves the same for "\\\\&"
- } else if (escape_type == 4) {
- gsub(/[]\\ "'$q'`$|&;<>()!^*?[]/, "\\\\&", text);
- if (escape_c) gsub(/[=:]/, "\\\\&", text);
- if (escape_b) gsub(/[{,}]/, "\\\\&", text);
- if (ret ~ /^~/ && (escape_tilde_always || escape_tilde_exists && exists(cand)))
- text = "\\" text;
- gsub(/\n/, "$" q REP_SL "n" q, text);
- gsub(/\t/, "$" q REP_SL "t" q, text);
- }
- return text;
- }
- function quote_insert(cand) {
- if (quote_action == "command") {
- if (comps == compv && cand ~ /^(\[\[|]]|!)$/) return cand;
- } else if (quote_action == "progcomp") {
- if (is_noquote) return cand;
- if (is_nospace && cand ~ / $/ && !is_file(cand)) return cand;
- }
- if (comps_v && substr(cand, 1, compv_len) == compv) {
- ins = escape_for_completion_context(substr(cand, compv_len + 1));
- if (comps_p && ins ~ /^[_a-zA-Z0-9]/) {
- return quote_paramx_comps ins;
- } else {
- if (quote_cont_cutbackslash) sub(/^\\/, "", ins);
- return comps ins;
- }
- } else if (quote_fixed_comps_len && substr(cand, 1, quote_fixed_compv_len) == quote_fixed_compv) {
- ins = substr(cand, quote_fixed_compv_len + 1);
- return quote_fixed_comps quote_trav_prefix escape_for_completion_context(ins);
- } else {
- return quote_trav_prefix escape_for_completion_context(cand);
- }
- }
- {
- cand = substr($0, 3);
- insert = quote_insert(cand);
- printf("%s%c", insert, DELIM);
- }
- '
-}
-function ble/complete/action/quote-insert.batch/proc {
- local _ble_local_tmpfile; ble/util/assign/.mktmp
- local delim='\n'
- [[ $quote_batch_nulsep ]] && delim='\0'
- if [[ $quote_action == progcomp ]]; then
- local cand file exist
- for cand in "${cands[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- f=0 e=0
- [[ -e $cand ]] && e=1
- [[ -f $cand ]] && f=1
- printf "$e$f%s$delim" "$cand"
- done
- else
- printf "00%s$delim" "${cands[@]}"
- fi >| "$_ble_local_tmpfile"
- local fname_cands=$_ble_local_tmpfile
- ble/util/conditional-sync \
- 'ble/complete/action/quote-insert.batch/awk < "$fname_cands"' \
- '! ble/complete/check-cancel < /dev/tty' '' progressive-weight
- local ext=$?
- ble/util/assign/.rmtmp
- return "$ext"
-}
-function ble/complete/action/quote-insert.batch {
- local opts=$1
- local quote_batch_nulsep=
- local quote_batch_awk=ble/bin/awk
- if [[ :$opts: != *:newline:* ]]; then
- if ((_ble_bash>=40400)); then
- if [[ $_ble_bin_awk_type == [mg]awk ]]; then
- quote_batch_nulsep=1
- elif ble/bin#has mawk; then
- quote_batch_nulsep=1
- quote_batch_awk=mawk
- elif ble/bin#has gawk; then
- quote_batch_nulsep=1
- quote_batch_awk=gawk
- fi
- fi
- [[ ! $quote_batch_nulsep ]] &&
- [[ "${cands[*]}" == *$'\n'* ]] &&
- return 1
- fi
- if [[ $quote_batch_nulsep ]]; then
- ble/util/assign-array0 inserts ble/complete/action/quote-insert.batch/proc
- else
- ble/util/assign-array inserts ble/complete/action/quote-insert.batch/proc
- fi
- return $?
-}
-function ble/complete/action/requote-final-insert {
- local comps_prefix= check_optarg=
- if [[ $insert == "$COMPS"* ]]; then
- [[ $comps_flags == *[SEDI]* ]] && return 0
- [[ $COMPS != *[!':/={,'] ]] && comps_prefix=$COMPS
- check_optarg=$COMPS
- else
- check_optarg=$insert
- fi
- if [[ $check_optarg ]]; then
- if ble/string#match "$check_optarg" '^([_a-zA-Z][_a-zA-Z0-9]*|-[-a-zA-Z0-9.]+)=(([^\'\''"`${}]*|\\.)*:)?'; then
- comps_prefix=$BASH_REMATCH
- elif [[ $COMP_PREFIX == -[!'-=:/\'\''"$`{};&|<>!^{}'] && $check_optarg == "$COMP_PREFIX"* ]]; then
- comps_prefix=${check_optarg::2}
- fi
- fi
- if [[ $comps_fixed ]]; then
- local comps_fixed_part=${COMPS::${comps_fixed%%:*}}
- [[ $comps_prefix == "$comps_fixed_part"* ]] ||
- comps_prefix=$comps_fixed_part
- fi
- if [[ $insert == "$comps_prefix"* && $comps_prefix != *[!':/={,'] ]]; then
- local ret ins=${insert:${#comps_prefix}}
- if ! ble/syntax:bash/simple-word/is-literal "$ins" &&
- ble/syntax:bash/simple-word/is-simple "$ins" &&
- ble/syntax:bash/simple-word/eval "$ins" &&
- ((${#ret[@]}==1))
- then
- ble/string#quote-word "$ret" quote-empty
- ((${#ret}<=${#ins})) || return 0
- insert=$comps_prefix$ret
- [[ $insert == "$COMPS"* ]] || insert_flags=r$insert_flags # 遡って書き換えた
- fi
- fi
- return 0
-}
-function ble/complete/action#inherit-from {
- local dst=$1 src=$2
- local member srcfunc dstfunc
- for member in initialize{,.batch} complete getg get-desc; do
- srcfunc=ble/complete/action:$src/$member
- dstfunc=ble/complete/action:$dst/$member
- ble/is-function "$srcfunc" && builtin eval "function $dstfunc { $srcfunc; }"
- done
-}
-function ble/complete/action:plain/initialize {
- ble/complete/action/quote-insert
-}
-function ble/complete/action:plain/initialize.batch {
- ble/complete/action/quote-insert.batch
-}
-function ble/complete/action:plain/complete {
- ble/complete/action/requote-final-insert
-}
-function ble/complete/action:literal-substr/initialize { :; }
-function ble/complete/action:literal-substr/initialize.batch { inserts=("${cands[@]}"); }
-function ble/complete/action:literal-substr/complete { :; }
-function ble/complete/action:substr/initialize {
- ble/complete/action/quote-insert
-}
-function ble/complete/action:substr/initialize.batch {
- ble/complete/action/quote-insert.batch
-}
-function ble/complete/action:substr/complete {
- ble/complete/action/requote-final-insert
-}
-function ble/complete/action:literal-word/initialize { :; }
-function ble/complete/action:literal-word/initialize.batch { inserts=("${cands[@]}"); }
-function ble/complete/action:literal-word/complete {
- if [[ $comps_flags == *x* ]]; then
- ble/complete/action/complete.addtail ','
- else
- ble/complete/action/complete.addtail ' '
- fi
-}
-function ble/complete/action:word/initialize {
- ble/complete/action/quote-insert
-}
-function ble/complete/action:word/initialize.batch {
- ble/complete/action/quote-insert.batch
-}
-function ble/complete/action:word/complete {
- ble/complete/action/requote-final-insert
- ble/complete/action/complete.close-quotation
- ble/complete/action:literal-word/complete
-}
-function ble/complete/action:word/get-desc {
- [[ $DATA ]] && desc=$DATA
-}
-function ble/complete/action:file/initialize {
- ble/complete/action/quote-insert
-}
-function ble/complete/action:file/initialize.batch {
- ble/complete/action/quote-insert.batch
-}
-function ble/complete/action:file/complete {
- ble/complete/action/requote-final-insert
- if [[ -e $CAND || -h $CAND ]]; then
- if [[ -d $CAND ]]; then
- ble/complete/action/complete.mark-directory
- else
- ble/complete/action:word/complete
- fi
- fi
-}
-function ble/complete/action:file/init-menu-item {
- ble/syntax/highlight/getg-from-filename "$CAND"
- [[ $g ]] || { local ret; ble/color/face2g filename_warning; g=$ret; }
- if [[ :$comp_type: == *:vstat:* ]]; then
- if [[ -h $CAND ]]; then
- suffix='@'
- elif [[ -d $CAND ]]; then
- suffix='/'
- elif [[ -x $CAND ]]; then
- suffix='*'
- fi
- fi
-}
-function ble/complete/action:file_rhs/initialize {
- ble/complete/action:file/initialize
-}
-function ble/complete/action:file_rhs/initialize.batch {
- ble/complete/action:file/initialize.batch
-}
-function ble/complete/action:file_rhs/complete {
- CAND=${CAND:${#DATA}} ble/complete/action:file/complete
-}
-function ble/complete/action:file_rhs/init-menu-item {
- CAND=${CAND:${#DATA}} ble/complete/action:file/init-menu-item
-}
-_ble_complete_action_file_desc[_ble_attr_FILE_LINK]='symbolic link'
-_ble_complete_action_file_desc[_ble_attr_FILE_ORPHAN]='symbolic link (orphan)'
-_ble_complete_action_file_desc[_ble_attr_FILE_DIR]='directory'
-_ble_complete_action_file_desc[_ble_attr_FILE_STICKY]='directory (sticky)'
-_ble_complete_action_file_desc[_ble_attr_FILE_SETUID]='file (setuid)'
-_ble_complete_action_file_desc[_ble_attr_FILE_SETGID]='file (setgid)'
-_ble_complete_action_file_desc[_ble_attr_FILE_EXEC]='file (executable)'
-_ble_complete_action_file_desc[_ble_attr_FILE_FILE]='file'
-_ble_complete_action_file_desc[_ble_attr_FILE_CHR]='character device'
-_ble_complete_action_file_desc[_ble_attr_FILE_FIFO]='named pipe'
-_ble_complete_action_file_desc[_ble_attr_FILE_SOCK]='socket'
-_ble_complete_action_file_desc[_ble_attr_FILE_BLK]='block device'
-_ble_complete_action_file_desc[_ble_attr_FILE_URL]='URL'
-function ble/complete/action:file/get-desc {
- local type; ble/syntax/highlight/filetype "$CAND"
- desc=${_ble_complete_action_file_desc[type]:-'file (???)'}
-}
-function ble/complete/action:progcomp/initialize/.reconstruct-from-noquote {
- local simple_flags simple_ibrace ret count
- ble/syntax:bash/simple-word/is-simple-or-open-simple "$INSERT" &&
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$INSERT" &&
- ble/complete/source/eval-simple-word "$ret" single:count &&
- ((count==1)) || return 0
- CAND=$ret
- if [[ $quote_fixed_comps && $CAND == "$quote_fixed_compv"* ]]; then
- local ret; ble/complete/string#escape-for-completion-context "${CAND:quote_fixed_compv_len}" "$escape_flags"
- INSERT=$quote_fixed_comps$quote_trav_prefix$ret
- return 3
- fi
- return 0
-}
-function ble/complete/action:progcomp/initialize {
- if [[ :$DATA: == *:noquote:* ]]; then
- local progcomp_resolve_brace=$quote_fixed_comps
- [[ :$DATA: == *:ble/syntax-raw:* ]] && progcomp_resolve_brace=
- ble/complete/action:progcomp/initialize/.reconstruct-from-noquote
- return 0
- else
- ble/complete/action/quote-insert progcomp
- fi
-}
-function ble/complete/action:progcomp/initialize.batch {
- if [[ :$DATA: == *:noquote:* ]]; then
- inserts=("${cands[@]}")
- local progcomp_resolve_brace=$quote_fixed_comps
- [[ :$DATA: == *:ble/syntax-raw:* ]] && progcomp_resolve_brace=
- cands=()
- local INSERT simple_flags simple_ibrace ret count icand=0
- for INSERT in "${inserts[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- local CAND=$INSERT
- ble/complete/action:progcomp/initialize/.reconstruct-from-noquote ||
- inserts[icand]=$INSERT # INSERT を上書きした時 ($?==3)
- cands[icand++]=$CAND
- done
- else
- ble/complete/action/quote-insert.batch newline
- fi
-}
-function ble/complete/action:progcomp/complete {
- if [[ $DATA == *:filenames:* ]]; then
- ble/complete/action:file/complete
- else
- if [[ $DATA != *:ble/no-mark-directories:* && -d $CAND ]]; then
- ble/complete/action/requote-final-insert
- ble/complete/action/complete.mark-directory
- else
- ble/complete/action:word/complete
- fi
- fi
- [[ $DATA == *:nospace:* ]] && suffix=${suffix%' '}
- [[ $DATA == *:ble/no-mark-directories:* && -d $CAND ]] && suffix=${suffix%/}
-}
-function ble/complete/action:progcomp/init-menu-item {
- if [[ $DATA == *:filenames:* ]]; then
- ble/complete/action:file/init-menu-item
- fi
-}
-function ble/complete/action:progcomp/get-desc {
- if [[ $DATA == *:filenames:* ]]; then
- ble/complete/action:file/get-desc
- fi
-}
-function ble/complete/action:command/initialize {
- ble/complete/action/quote-insert command
-}
-function ble/complete/action:command/initialize.batch {
- ble/complete/action/quote-insert.batch newline
-}
-function ble/complete/action:command/complete {
- if [[ -d $CAND ]]; then
- ble/complete/action/complete.mark-directory
- elif ! type "$CAND" &>/dev/null; then
- if [[ $CAND == */ ]]; then
- insert_flags=${insert_flags}n
- fi
- else
- ble/complete/action:word/complete
- fi
-}
-function ble/complete/action:command/init-menu-item {
- if [[ -d $CAND ]]; then
- local ret; ble/color/face2g filename_directory; g=$ret
- else
- local type
- if [[ $CAND != "$INSERT" ]]; then
- ble/syntax/highlight/cmdtype "$CAND" "$INSERT"
- else
- local type; ble/util/type type "$CAND"
- ble/syntax/highlight/cmdtype1 "$type" "$CAND"
- fi
- if [[ $CAND == */ ]] && ((type==_ble_attr_ERR)); then
- type=_ble_attr_CMD_FUNCTION
- fi
- ble/syntax/attr2g "$type"
- fi
-}
-_ble_complete_action_command_desc[_ble_attr_CMD_BOLD]=builtin
-_ble_complete_action_command_desc[_ble_attr_CMD_BUILTIN]=builtin
-_ble_complete_action_command_desc[_ble_attr_CMD_ALIAS]=alias
-_ble_complete_action_command_desc[_ble_attr_CMD_FUNCTION]=function
-_ble_complete_action_command_desc[_ble_attr_CMD_FILE]=file
-_ble_complete_action_command_desc[_ble_attr_KEYWORD]=command
-_ble_complete_action_command_desc[_ble_attr_CMD_JOBS]=job
-_ble_complete_action_command_desc[_ble_attr_ERR]='command ???'
-_ble_complete_action_command_desc[_ble_attr_CMD_DIR]=directory
-function ble/complete/action:command/get-desc {
- local title= value=
- if [[ -d $CAND ]]; then
- title=directory
- else
- local type; ble/util/type type "$CAND"
- ble/syntax/highlight/cmdtype1 "$type" "$CAND"
- case $type in
- ($_ble_attr_CMD_ALIAS)
- local ret
- ble/alias#expand "$CAND"
- title=alias value=$ret ;;
- ($_ble_attr_CMD_FILE)
- local path; ble/util/assign path 'type -p -- "$CAND"'
- [[ $path == ?*/"$CAND" ]] && path="from ${path%/"$CAND"}"
- title=file value=$path ;;
- ($_ble_attr_CMD_FUNCTION)
- local source lineno
- ble/function#get-source-and-lineno "$CAND"
- local def; ble/function#getdef "$CAND"
- ble/string#match "$def" '^[^()]*\(\)[[:space:]]*\{[[:space:]]+(.*[^[:space:]])[[:space:]]+\}[[:space:]]*$' &&
- def=${BASH_REMATCH[1]} # 関数の中身を抽出する
- local ret sgr0=$'\e[27m' sgr1=$'\e[7m' # Note: sgr-ansi で生成
- lines=1 cols=${COLUMNS:-80} x=0 y=0 ble/canvas/trace-text "$def" external-sgr
- title=function value="${source##*/}:$lineno $desc_sgrq$ret" ;;
- ($_ble_attr_CMD_JOBS)
- ble/util/joblist.check
- local job; ble/util/assign job 'jobs -- "$CAND" 2>/dev/null' || job='???'
- title=job value=${job:-(ambiguous)} ;;
- ($_ble_attr_ERR)
- if [[ $CAND == */ ]]; then
- title='function namespace'
- else
- title=${_ble_complete_action_command_desc[_ble_attr_ERR]}
- fi ;;
- (*)
- title=${_ble_complete_action_command_desc[type]:-'???'} ;;
- esac
- fi
- desc=${title:+$desc_sgrt($title)$desc_sgr0}${value:+ $value}
-}
-function ble/complete/action:variable/initialize { ble/complete/action/quote-insert; }
-function ble/complete/action:variable/initialize.batch { ble/complete/action/quote-insert.batch newline; }
-function ble/complete/action:variable/complete {
- case $DATA in
- (assignment)
- ble/complete/action/complete.addtail '=' ;;
- (braced)
- ble/complete/action/complete.addtail '}' ;;
- (word) ble/complete/action:word/complete ;;
- (arithmetic|nosuffix) ;; # do nothing
- esac
-}
-function ble/complete/action:variable/init-menu-item {
- local ret; ble/color/face2g syntax_varname; g=$ret
-}
-function ble/complete/action:variable/get-desc {
- local _ble_local_title=variable
- if ble/is-array "$CAND"; then
- _ble_local_title=array
- elif ble/is-assoc "$CAND"; then
- _ble_local_title=assoc
- fi
- local _ble_local_value=
- if [[ $_ble_local_title == array || $_ble_local_title == assoc ]]; then
- builtin eval "local count=\${#$CAND[@]}"
- if ((count==0)); then
- count=empty
- else
- count="$count items"
- fi
- _ble_local_value=$'\e[94m['$count$']\e[m'
- else
- local ret; ble/string#quote-word "${!CAND}" ansi:sgrq="$desc_sgrq":quote-empty
- _ble_local_value=$ret
- fi
- desc="$desc_sgrt($_ble_local_title)$desc_sgr0 $_ble_local_value"
-}
-function ble/complete/source/test-limit {
- local value=$1 limit=
- if [[ :$comp_type: == *:auto_menu:* && $bleopt_complete_limit_auto_menu ]]; then
- limit=$bleopt_complete_limit_auto_menu
- elif [[ :$comp_type: == *:auto:* && $bleopt_complete_limit_auto ]]; then
- limit=$bleopt_complete_limit_auto
- else
- limit=$bleopt_complete_limit
- fi
- if [[ $limit && value -gt limit ]]; then
- cand_limit_reached=1
- [[ :$comp_type: == *:auto_menu: ]] && cand_limit_reached=cancel
- return 1
- else
- return 0
- fi
-}
-function ble/complete/source/eval-simple-word {
- local word=$1 opts=$2
- if [[ :$comp_type: != *:sync:* && :$opts: != *:noglob:* ]]; then
- opts=$opts:stopcheck:cached
- [[ :$comp_type: == *:auto:* && $bleopt_complete_timeout_auto ]] &&
- opts=$opts:timeout=$((bleopt_complete_timeout_auto))
- fi
- ble/syntax:bash/simple-word/eval "$word" "$opts"; local ext=$?
- ((ext==142)) && return 148
- return "$ext"
-}
-function ble/complete/source/evaluate-path-spec {
- local word=$1 sep=$2 opts=$3
- if [[ :$comp_type: != *:sync:* && :$opts: != *:noglob:* ]]; then
- opts=$opts:stopcheck:cached:single
- [[ :$comp_type: == *:auto:* && $bleopt_complete_timeout_auto ]] &&
- opts=$opts:timeout=$((bleopt_complete_timeout_auto))
- fi
- ble/syntax:bash/simple-word/evaluate-path-spec "$word" "$sep" "$opts"; local ext=$?
- ((ext==142)) && return 148
- return "$ext"
-}
-function ble/complete/source/reduce-compv-for-ambiguous-match {
- [[ :$comp_type: == *:[maA]:* ]] || return 0
- local comps=$COMPS compv=$COMPV
- local comps_prefix= compv_prefix=
- if [[ $comps_fixed ]]; then
- comps_prefix=${comps::${comps_fixed%%:*}}
- compv_prefix=${comps_fixed#*:}
- compv=${COMPV:${#compv_prefix}}
- fi
- case $comps_flags in
- (*S*) comps_prefix=$comps_prefix\' ;;
- (*E*) comps_prefix=$comps_prefix\$\' ;;
- (*D*) comps_prefix=$comps_prefix\" ;;
- (*I*) comps_prefix=$comps_prefix\$\" ;;
- esac
- if [[ $compv && :$comp_type: == *:a:* ]]; then
- compv=${compv::1}
- ble/complete/string#escape-for-completion-context "$compv"
- comps=$ret
- else
- compv= comps=
- fi
- COMPV=$compv_prefix$compv
- COMPS=$comps_prefix$comps
-}
-_ble_complete_yield_varnames=("${_ble_complete_quote_insert_varnames[@]}")
-function ble/complete/cand/yield.initialize {
- ble/complete/action/quote-insert.initialize "$1"
-}
-function ble/complete/cand/yield {
- local ACTION=$1 CAND=$2 DATA=$3
- [[ $flag_force_fignore ]] && ! ble/complete/.fignore/filter "$CAND" && return 0
- [[ $flag_source_filter ]] || ble/complete/candidates/filter#test "$CAND" || return 0
- local INSERT=$CAND
- ble/complete/action:"$ACTION"/initialize || return "$?"
- local PREFIX_LEN=0
- [[ $CAND == "$COMP_PREFIX"* ]] && PREFIX_LEN=${#COMP_PREFIX}
- local icand
- ((icand=cand_count++))
- cand_cand[icand]=$CAND
- cand_word[icand]=$INSERT
- cand_pack[icand]=$ACTION:${#CAND},${#INSERT},$PREFIX_LEN:$CAND$INSERT$DATA
-}
-function ble/complete/cand/yield.batch {
- local ACTION=$1 DATA=$2
- local inserts threshold=500
- [[ $OSTYPE == cygwin* || $OSTYPE == msys* ]] && threshold=2000
- if ((${#cands[@]}>=threshold)) && ble/function#try ble/complete/action:"$ACTION"/initialize.batch; then
- local i n=${#cands[@]}
- for ((i=0;i<n;i++)); do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- local CAND=${cands[i]} INSERT=${inserts[i]}
- [[ $flag_force_fignore ]] && ! ble/complete/.fignore/filter "$CAND" && continue
- [[ $flag_source_filter ]] || ble/complete/candidates/filter#test "$CAND" || continue
- local PREFIX_LEN=0
- [[ $CAND == "$COMP_PREFIX"* ]] && PREFIX_LEN=${#COMP_PREFIX}
- local icand
- ((icand=cand_count++))
- cand_cand[icand]=$CAND
- cand_word[icand]=$INSERT
- cand_pack[icand]=$ACTION:${#CAND},${#INSERT},$PREFIX_LEN:$CAND$INSERT$DATA
- done
- else
- local cand
- for cand in "${cands[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- ble/complete/cand/yield "$ACTION" "$cand" "$DATA"
- done
- fi
-}
-function ble/complete/cand/yield-filenames {
- local action=$1; shift
- local rex_hidden=
- [[ :$comp_type: != *:match-hidden:* ]] &&
- rex_hidden=${COMPV:+'.{'${#COMPV}'}'}'(^|/)\.[^/]*$'
- local -a cands=()
- local cand icand=0
- for cand; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- [[ $rex_hidden && $cand =~ $rex_hidden ]] && continue
- cands[icand++]=$cand
- done
- [[ $FIGNORE ]] && local flag_force_fignore=1
- local "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- ble/complete/cand/yield.batch "$action"
-}
-_ble_complete_cand_varnames=(ACTION CAND INSERT DATA PREFIX_LEN)
-function ble/complete/cand/unpack {
- local pack=$1
- ACTION=${pack%%:*} pack=${pack#*:}
- local text=${pack#*:}
- IFS=, builtin eval 'pack=(${pack%%:*})'
- CAND=${text::pack[0]}
- INSERT=${text:pack[0]:pack[1]}
- DATA=${text:pack[0]+pack[1]}
- PREFIX_LEN=${pack[2]}
-}
-function ble/complete/source:none { return 0; }
-function ble/complete/source:wordlist {
- [[ $comps_flags == *v* ]] || return 1
- local COMPS=$COMPS COMPV=$COMPV
- ble/complete/source/reduce-compv-for-ambiguous-match
- [[ $COMPV =~ ^.+/ ]] && COMP_PREFIX=${BASH_REMATCH[0]}
- local opt_raw= opt_noword= opt_sabbrev=
- while (($#)) && [[ $1 == -* ]]; do
- local arg=$1; shift
- case $arg in
- (--) break ;;
- (--*) ;; # ignore
- (-*)
- local i iN=${#arg}
- for ((i=1;i<iN;i++)); do
- case ${arg:i:1} in
- (r) opt_raw=1 ;;
- (W) opt_noword=1 ;;
- (s) opt_sabbrev=1 ;;
- (*) ;; # ignore
- esac
- done ;;
- esac
- done
- [[ $opt_sabbrev ]] &&
- ble/complete/source:sabbrev
- local action=word
- [[ $opt_noword ]] && action=substr
- [[ $opt_raw ]] && action=literal-$action
- local cand "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- for cand; do
- [[ $cand == "$COMPV"* ]] && ble/complete/cand/yield "$action" "$cand"
- done
-}
-function ble/complete/source:command/.contract-by-slashes {
- local slashes=${COMPV//[!'/']}
- ble/bin/awk -F / -v baseNF=${#slashes} '
- function initialize_common() {
- common_NF = NF;
- for (i = 1; i <= NF; i++) common[i] = $i;
- common_degeneracy = 1;
- common0_NF = NF;
- common0_str = $0;
- }
- function print_common(_, output) {
- if (!common_NF) return;
- if (common_degeneracy == 1) {
- print common0_str;
- common_NF = 0;
- return;
- }
- output = common[1];
- for (i = 2; i <= common_NF; i++)
- output = output "/" common[i];
- if (common_NF == common0_NF) print output;
- print output "/";
- common_NF = 0;
- }
- {
- if (NF <= baseNF + 1) {
- print_common();
- print $0;
- } else if (!common_NF) {
- initialize_common();
- } else {
- n = common_NF < NF ? common_NF : NF;
- for (i = baseNF + 1; i <= n; i++)
- if (common[i] != $i) break;
- matched_length = i - 1;
- if (matched_length <= baseNF) {
- print_common();
- initialize_common();
- } else {
- common_NF = matched_length;
- common_degeneracy++;
- }
- }
- }
- END { print_common(); }
- '
-}
-function ble/complete/source:command/gen.1 {
- local COMPS=$COMPS COMPV=$COMPV
- ble/complete/source/reduce-compv-for-ambiguous-match
- local slow_compgen=
- if [[ ! $COMPV ]]; then
- slow_compgen=1
- elif [[ $OSTYPE == cygwin* ]]; then
- case $COMPV in
- (?|cy*|x8*|i6*)
- slow_compgen=1 ;;
- esac
- fi
- if [[ $slow_compgen ]]; then
- shopt -q no_empty_cmd_completion && return 0
- ble/util/conditional-sync \
- 'builtin compgen -c -- "$COMPV"' \
- '! ble/complete/check-cancel' 128 progressive-weight
- else
- builtin compgen -c -- "$COMPV"
- fi
- if [[ $COMPV == */* ]]; then
- local q="'" Q="'\''"
- local compv_quoted="'${COMPV//$q/$Q}'"
- builtin compgen -A function -- "$compv_quoted"
- fi
-}
-function ble/complete/source:command/gen {
- if [[ :$comp_type: != *:[maA]:* && $bleopt_complete_contract_function_names ]]; then
- ble/complete/source:command/gen.1 |
- ble/complete/source:command/.contract-by-slashes
- else
- ble/complete/source:command/gen.1
- fi
- if [[ $arg != *D* ]]; then
- local ret
- ble/complete/source:file/.construct-pathname-pattern "$COMPV"
- ble/complete/util/eval-pathname-expansion "$ret/"; (($?==148)) && return 148
- ble/complete/source/test-limit ${#ret[@]} || return 1
- ((${#ret[@]})) && printf '%s\n' "${ret[@]}"
- fi
- if [[ ! $COMPV || $COMPV == %* ]]; then
- local q="'" Q="'\''"
- local compv_quoted=${COMPV#'%'}
- compv_quoted="'${compv_quoted//$q/$Q}'"
- builtin compgen -j -P % -- "$compv_quoted"
- local i joblist; ble/util/joblist
- local job_count=${#joblist[@]}
- for i in "${!joblist[@]}"; do
- if local rex='^\[([0-9]+)\]'; [[ ${joblist[i]} =~ $rex ]]; then
- joblist[i]=%${BASH_REMATCH[1]}
- else
- builtin unset -v 'joblist[i]'
- fi
- done
- joblist=("${joblist[@]}")
- if ((job_count>0)); then
- ble/array#push joblist %% %+
- ((job_count>=2)) &&
- ble/array#push joblist %-
- fi
- builtin compgen -W '"${joblist[@]}"' -- "$compv_quoted"
- fi
-}
-function ble/complete/source:command {
- [[ $comps_flags == *v* ]] || return 1
- [[ ! $COMPV ]] && shopt -q no_empty_cmd_completion && return 1
- [[ $COMPV =~ ^.+/ ]] && COMP_PREFIX=${BASH_REMATCH[0]}
- local arg=$1
- {
- local old_cand_count=$cand_count
- local comp_opts=:
- ble/complete/source:argument/.generate-user-defined-completion initial; local ext=$?
- ((ext==148)) && return "$ext"
- if ((ext==0)); then
- ((cand_count>old_cand_count)) && return "$ext"
- fi
- }
- ble/complete/source:sabbrev
- local arr
- local compgen
- ble/util/assign compgen 'ble/complete/source:command/gen "$arg"'
- [[ $compgen ]] || return 1
- ble/util/assign-array arr 'ble/bin/sort -u <<< "$compgen"' # 1 fork/exec
- ble/complete/source/test-limit ${#arr[@]} || return 1
- local action=command "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- local is_quoted=
- [[ $COMPS != "$COMPV" ]] && is_quoted=1
- local rex_keyword='^(if|then|else|elif|fi|case|esac|for|select|while|until|do|done|function|time|[!{}]|\[\[|coproc|\]\]|in)$'
- local expand_aliases=
- shopt -q expand_aliases && expand_aliases=1
- local cand icand=0 cands
- for cand in "${arr[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- [[ $cand != */ && -d $cand ]] && ! type "$cand" &>/dev/null && continue
- if [[ $is_quoted ]]; then
- local disable_count=
- [[ $cand =~ $rex_keyword ]] && ((disable_count++))
- [[ $expand_aliases ]] && ble/is-alias "$cand" && ((disable_count++))
- if [[ $disable_count ]]; then
- local type; ble/util/type type "$cand"
- ((${#type[@]}>disable_count)) || continue
- fi
- else
- [[ $cand == ']]' || $cand == in ]] &&
- ! { [[ $expand_aliases ]] && ble/is-alias "$cand"; } &&
- continue
- if [[ ! $expand_aliases ]]; then
- ble/is-alias "$cand" && ! type "$cand" &>/dev/null && continue
- fi
- if ble/string#match "$cand" '[][*?{,}!^~#]' && ble/is-alias "$cand"; then
- ble/complete/cand/yield "$action" "$cand" :noquote:
- continue
- fi
- fi
- cands[icand++]=$cand
- done
- ble/complete/cand/yield.batch "$action"
-}
-function ble/complete/util/eval-pathname-expansion/.print-def {
- local pattern=$1 ret
- IFS= builtin eval "ret=($pattern)" 2>/dev/null
- ble/string#quote-words "${ret[@]}"
- ble/util/print "ret=($ret)"
-}
-function ble/complete/util/eval-pathname-expansion {
- local pattern=$1
- local -a dtor=()
- if [[ -o noglob ]]; then
- set +f
- ble/array#push dtor 'set -f'
- fi
- if ! shopt -q nullglob; then
- shopt -s nullglob
- ble/array#push dtor 'shopt -u nullglob'
- fi
- if ! shopt -q dotglob; then
- shopt -s dotglob
- ble/array#push dtor 'shopt -u dotglob'
- else
- ble/array#push dtor 'shopt -s dotglob'
- fi
- if ! shopt -q extglob; then
- shopt -s extglob
- ble/array#push dtor 'shopt -u extglob'
- fi
- if [[ :$comp_type: == *:i:* ]]; then
- if ! shopt -q nocaseglob; then
- shopt -s nocaseglob
- ble/array#push dtor 'shopt -u nocaseglob'
- fi
- else
- if shopt -q nocaseglob; then
- shopt -u nocaseglob
- ble/array#push dtor 'shopt -s nocaseglob'
- fi
- fi
- if ble/util/is-cygwin-slow-glob "$pattern"; then # Note: #D1168
- if shopt -q failglob &>/dev/null || shopt -q nullglob &>/dev/null; then
- pattern=
- else
- set -f
- ble/array#push dtor 'set +f'
- fi
- fi
- if [[ $GLOBIGNORE ]]; then
- local GLOBIGNORE_save=$GLOBIGNORE
- GLOBIGNORE=
- ble/array#push dtor 'GLOBIGNORE=$GLOBIGNORE_save'
- fi
- ble/array#reverse dtor
- ret=()
- if [[ :$comp_type: == *:sync:* ]]; then
- IFS= builtin eval "ret=($pattern)" 2>/dev/null
- else
- local sync_command='ble/complete/util/eval-pathname-expansion/.print-def "$pattern"'
- local sync_opts=progressive-weight
- [[ :$comp_type: == *:auto:* && $bleopt_complete_timeout_auto ]] &&
- sync_opts=$sync_opts:timeout=$((bleopt_complete_timeout_auto))
- local def
- ble/util/assign def 'ble/util/conditional-sync "$sync_command" "" "" "$sync_opts"' &>/dev/null; local ext=$?
- if ((ext==148)) || ble/complete/check-cancel; then
- ble/util/invoke-hook dtor
- return 148
- fi
- builtin eval -- "$def"
- fi 2>&$_ble_util_fd_stderr
- ble/util/invoke-hook dtor
- return 0
-}
-function ble/complete/source:file/.construct-ambiguous-pathname-pattern {
- local path=$1 fixlen=${2:-1}
- local pattern= i=0 j
- local names; ble/string#split names / "$1"
- local name
- for name in "${names[@]}"; do
- ((i++)) && pattern=$pattern/
- if [[ $name ]]; then
- ble/string#quote-word "${name::fixlen}"
- pattern=$pattern$ret*
- for ((j=fixlen;j<${#name};j++)); do
- ble/string#quote-word "${name:j:1}"
- if [[ $_ble_bash -lt 50000 && $pattern == *\* ]]; then
- pattern=$pattern'([!'$ret'])'
- fi
- pattern=$pattern$ret*
- done
- fi
- done
- [[ $pattern == *'*' ]] || pattern=$pattern*
- ret=$pattern
-}
-function ble/complete/source:file/.construct-pathname-pattern {
- local path=$1 pattern
- case :$comp_type: in
- (*:a:*) ble/complete/source:file/.construct-ambiguous-pathname-pattern "$path"; pattern=$ret ;;
- (*:A:*) ble/complete/source:file/.construct-ambiguous-pathname-pattern "$path" 0; pattern=$ret ;;
- (*:m:*) ble/string#quote-word "$path"; pattern=*$ret* ;;
- (*) ble/string#quote-word "$path"; pattern=$ret*
- esac
- ret=$pattern
-}
-function ble/complete/source:file/.impl {
- local opts=$1
- [[ $comps_flags == *v* ]] || return 1
- [[ :$comp_type: != *:[maA]:* && $COMPV =~ ^.+/ ]] && COMP_PREFIX=${BASH_REMATCH[0]}
- [[ :$comp_type: == *:[maA]:* && ! $COMPV ]] && return 1
- ble/complete/source:tilde; local ext=$?
- ((ext==148||ext==0)) && return "$ext"
- local -a candidates=()
- local ret
- ble/complete/source:file/.construct-pathname-pattern "$COMPV"
- [[ :$opts: == *:directory:* ]] && ret=$ret/
- ble/complete/util/eval-pathname-expansion "$ret"; (($?==148)) && return 148
- ble/complete/source/test-limit ${#ret[@]} || return 1
- if [[ :$opts: == *:directory:* ]]; then
- candidates=("${ret[@]%/}")
- else
- candidates=("${ret[@]}")
- fi
- [[ :$opts: == *:no-fd:* ]] &&
- ble/array#remove-by-regex candidates '^[0-9]+-?$|^-$'
- local flag_source_filter=1
- ble/complete/cand/yield-filenames file "${candidates[@]}"
-}
-function ble/complete/source:file {
- ble/complete/source:file/.impl "$1"
-}
-function ble/complete/source:dir {
- ble/complete/source:file/.impl "directory:$1"
-}
-function ble/complete/source:rhs { ble/complete/source:file; }
-function ble/complete/action:tilde/initialize {
- CAND=${CAND#\~} ble/complete/action/quote-insert
- INSERT=\~$INSERT
- local rex='^~[^/'\''"$`\!:]*$'; [[ $INSERT =~ $rex ]]
-}
-function ble/complete/action:tilde/complete {
- ble/complete/action/complete.mark-directory
-}
-function ble/complete/action:tilde/init-menu-item {
- local ret
- ble/color/face2g filename_directory; g=$ret
-}
-function ble/complete/action:tilde/get-desc {
- if [[ $CAND == '~+' ]]; then
- desc='current directory (tilde expansion)'
- elif [[ $CAND == '~-' ]]; then
- desc='previous directory (tilde expansion)'
- elif local rex='^~[0-9]$'; [[ $CAND =~ $rex ]]; then
- desc='DIRSTACK directory (tilde expansion)'
- else
- desc='user directory (tilde expansion)'
- fi
-}
-function ble/complete/source:tilde/.generate {
- local pattern=${COMPS#\~}
- [[ :$comp_type: == *:[maA]:* ]] && pattern=
- builtin compgen -P \~ -u -- "$pattern"
- printf '%s\n' '~' '~+' '~-'
- local dirstack_max=$((${#DIRSTACK[@]}-1))
- ((dirstack_max>=0)) &&
- builtin eval "printf '%s\n' '~'{0..$dirstack_max}"
-}
-function ble/complete/source:tilde {
- local rex='^~[^/'\''"$`\!:]*$'; [[ $COMPS =~ $rex ]] || return 1
- local compgen candidates
- ble/util/assign compgen ble/complete/source:tilde/.generate
- [[ $compgen ]] || return 1
- ble/util/assign-array candidates 'ble/bin/sort -u <<< "$compgen"'
- local flag_source_filter=1
- if [[ $COMPS == '~'?* ]]; then
- local filter_type=$comp_filter_type
- [[ $filter_type == none ]] && filter_type=head
- local comp_filter_type
- local comp_filter_pattern
- ble/complete/candidates/filter#init "$filter_type" "$COMPS"
- ble/array#filter candidates ble/complete/candidates/filter#test
- fi
- ((${#candidates[@]})) || return 1
- local old_cand_count=$cand_count
- ble/complete/cand/yield-filenames tilde "${candidates[@]}"; local ext=$?
- return $((ext?ext:cand_count>old_cand_count))
-}
-function ble/complete/source:fd {
- IFS=: builtin eval 'local fdlist=":${_ble_util_openat_fdlist[*]}:"'
- [[ $comp_filter_type == none ]] &&
- local comp_filter_type=head
- local old_cand_count=$cand_count
- local action=word "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- ble/complete/cand/yield "$action" -
- if [[ -d /proc/self/fd ]]; then
- local ret
- ble/complete/util/eval-pathname-expansion '/proc/self/fd/*'
- local fd
- for fd in "${ret[@]}"; do
- fd=${fd#/proc/self/fd/}
- [[ ${fd//[0-9]} ]] && continue
- [[ $fdlist == *:"$fd":* ]] && continue
- ble/complete/cand/yield "$action" "$fd"
- ble/complete/cand/yield "$action" "$fd-"
- done
- else
- local fd
- for ((fd=0;fd<10;fd++)); do
- ble/fd#is-open "$fd" || continue
- ble/complete/cand/yield "$action" "$fd"
- ble/complete/cand/yield "$action" "$fd-"
- done
- fi
- return $((cand_count>old_cand_count))
-}
-function ble/complete/progcomp/.compvar-initialize-wordbreaks {
- local ifs=$_ble_term_IFS q=\'\" delim=';&|<>()' glob='[*?' hist='!^{' esc='`$\'
- local escaped=$ifs$q$delim$glob$hist$esc
- wordbreaks=${COMP_WORDBREAKS//[$escaped]} # =:
-}
-function ble/complete/progcomp/.compvar-perform-wordbreaks {
- local word=$1
- if [[ ! $word ]]; then
- ret=('')
- return 0
- fi
- ret=()
- while local head=${word%%["$wordbreaks"]*}; [[ $head != $word ]]; do
- ble/array#push ret "$head"
- word=${word:${#head}}
- head=${word%%[!"$wordbreaks"]*}
- ble/array#push ret "$head"
- word=${word:${#head}}
- done
- ble/array#push ret "$word"
-}
-function ble/complete/progcomp/.compvar-eval-word {
- local opts=$2:single
- if [[ :$opts: == *:noglob:* ]]; then
- ble/syntax:bash/simple-word/eval "$1" "$opts"
- else
- [[ $bleopt_complete_timeout_compvar ]] &&
- opts=timeout=$((bleopt_complete_timeout_compvar)):retry-noglob-on-timeout:$opts
- ble/complete/source/eval-simple-word "$1" "$opts"
- fi
-}
-function ble/complete/progcomp/.compvar-generate-subwords/impl1 {
- local word=$1 ret simple_flags simple_ibrace
- if [[ $point ]]; then
- local left=${word::point} right=${word:point}
- else
- local left=$word right=
- local point= # hide
- fi
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$left" || return 1
- left=$ret
- if [[ $right ]]; then
- case $simple_flags in
- (*I*) right=\$\"$right ;;
- (*D*) right=\"$right ;;
- (*E*) right=\$\'$right ;;
- (*S*) right=\'$right ;;
- (*B*) right=\\$right ;;
- esac
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$right" || return 1
- right=$ret
- fi
- point=0 words=()
- local eval_opts=noglob
- ((${#ret[@]}==1)) && eval_opts=
- ble/syntax:bash/simple-word#break-word "$left"
- local subword
- for subword in "${ret[@]}"; do
- ble/complete/progcomp/.compvar-eval-word "$subword" "$eval_opts"
- ble/array#push words "$ret"
- ((point+=${#ret}))
- done
- if [[ $right ]]; then
- ble/syntax:bash/simple-word#break-word "$right"
- local subword isfirst=1
- for subword in "${ret[@]}"; do
- ble/complete/progcomp/.compvar-eval-word "$subword" noglob
- if [[ $isfirst ]]; then
- isfirst=
- local iword=${#words[@]}; ((iword&&iword--))
- words[iword]=${words[iword]}$ret
- else
- ble/array#push words "$ret"
- fi
- done
- fi
- return 0
-}
-function ble/complete/progcomp/.compvar-generate-subwords/impl2 {
- local word=$1
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$word" || return 1
- ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148; local value1=$ret
- if [[ $point ]]; then
- if ((point==${#word})); then
- point=${#value1}
- elif ble/syntax:bash/simple-word/reconstruct-incomplete-word "${word::point}"; then
- ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148
- point=${#ret}
- fi
- fi
- ble/complete/progcomp/.compvar-perform-wordbreaks "$value1"; words=("${ret[@]}")
- return 0
-}
-function ble/complete/progcomp/.compvar-generate-subwords {
- local word1=$1 ret simple_flags simple_ibrace
- if [[ ! $word1 ]]; then
- subword_flags=E
- words=('')
- elif [[ $word1 == '~' ]]; then
- subword_flags=Q
- words=('~')
- elif ble/complete/progcomp/.compvar-generate-subwords/impl1 "$word1"; then
- subword_flags=E
- elif ble/complete/progcomp/.compvar-generate-subwords/impl2 "$word1"; then
- subword_flags=E
- else
- ble/complete/progcomp/.compvar-perform-wordbreaks "$word1"; words=("${ret[@]}")
- fi
-}
-function ble/complete/progcomp/.compvar-quote-subword {
- local word=$1 to_quote= is_evaluated= is_quoted=
- if [[ $subword_flags == *[EQ]* ]]; then
- [[ $subword_flags == *E* ]] && to_quote=1
- elif ble/syntax:bash/simple-word/reconstruct-incomplete-word "$word"; then
- is_evaluated=1
- ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148; word=$ret
- to_quote=1
- fi
- if [[ $to_quote ]]; then
- local shell_specialchars=']\ ["'\''`$|&;<>()*?{}!^'$'\n\t' q="'" Q="'\''" qq="''"
- if ((index>0)) && [[ $word == *["$shell_specialchars"]* || $word == [#~]* ]]; then
- is_quoted=1
- word="'${w//$q/$Q}'" word=${word#"$qq"} word=${word%"$qq"}
- fi
- fi
- if [[ $p && $word != "$1" ]]; then
- if ((p==${#1})); then
- p=${#word}
- else
- local left=${word::p}
- if [[ $is_evaluated ]]; then
- if ble/syntax:bash/simple-word/reconstruct-incomplete-word "$left"; then
- ble/complete/progcomp/.compvar-eval-word "$ret"; (($?==148)) && return 148; left=$ret
- fi
- fi
- if [[ $is_quoted ]]; then
- left="'${left//$q/$Q}" left=${left#"$qq"}
- fi
- p=${#left}
- fi
- fi
- ret=$word
-}
-function ble/complete/progcomp/.compvar-initialize {
- COMP_TYPE=9
- COMP_KEY=9
- ((${#KEYS[@]})) && COMP_KEY=${KEYS[${#KEYS[@]}-1]:-9} # KEYS defined in ble-decode/widget/.call-keyseq
- local wordbreaks
- ble/complete/progcomp/.compvar-initialize-wordbreaks
- progcomp_prefix=
- COMP_CWORD=
- COMP_POINT=
- COMP_LINE=
- COMP_WORDS=()
- local ret simple_flags simple_ibrace
- local word1 index=0 offset=0 sep=
- for word1 in "${comp_words[@]}"; do
- local point=$((comp_point-offset))
- ((0<=point&&point<=${#word1})) || point=
- ((offset+=${#word1}))
- local words subword_flags=
- ble/complete/progcomp/.compvar-generate-subwords "$word1"
- local w wq i=0 o=0 p
- for w in "${words[@]}"; do
- p=
- if [[ $point ]]; then
- ((p=point-o))
- ((i%2==0?p<=${#w}:p<${#w})) || p=
- ((o+=${#w},i++))
- fi
- [[ $p ]] && point=
- [[ $point ]] && progcomp_prefix=$progcomp_prefix$w
- ble/complete/progcomp/.compvar-quote-subword "$w"; local wq=$ret
- if [[ $p ]]; then
- COMP_CWORD=${#COMP_WORDS[*]}
- ((COMP_POINT=${#COMP_LINE}+${#sep}+p))
- fi
- ble/array#push COMP_WORDS "$wq"
- COMP_LINE=$COMP_LINE$sep$wq
- sep=
- done
- sep=' '
- ((offset++))
- ((index++))
- done
-}
-function ble/complete/progcomp/.compgen-helper-prog {
- if [[ $comp_prog ]]; then
- local COMP_WORDS COMP_CWORD
- local -x COMP_LINE COMP_POINT COMP_TYPE COMP_KEY
- ble/complete/progcomp/.compvar-initialize
- local cmd=${COMP_WORDS[0]} cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
- if [[ $comp_opts == *:ble/prog-trim:* ]]; then
- local compreply
- ble/util/assign compreply '"$comp_prog" "$cmd" "$cur" "$prev" < /dev/null'
- ble/bin/sed "s/[[:space:]]\{1,\}\$//" <<< "$compreply"
- else
- "$comp_prog" "$cmd" "$cur" "$prev" < /dev/null
- fi
- fi
-}
-function ble/complete/progcomp/compopt {
- local ext=0
- local -a ospec
- while (($#)); do
- local arg=$1; shift
- case "$arg" in
- (-*)
- local ic c
- for ((ic=1;ic<${#arg};ic++)); do
- c=${arg:ic:1}
- case "$c" in
- (o) ospec[${#ospec[@]}]="-$1"; shift ;;
- ([DE]) fDefault=1; break 2 ;;
- (*) ((ext==0&&(ext=1))) ;;
- esac
- done ;;
- (+o) ospec[${#ospec[@]}]="+$1"; shift ;;
- (*)
- return "$ext" ;;
- esac
- done
- local s
- for s in "${ospec[@]}"; do
- case "$s" in
- (-*) comp_opts=${comp_opts//:"${s:1}":/:}${s:1}: ;;
- (+*) comp_opts=${comp_opts//:"${s:1}":/:} ;;
- esac
- done
- return "$ext"
-}
-function ble/complete/progcomp/.check-limits {
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) &&
- [[ ! -t 0 ]] && ble/complete/check-cancel <&$_ble_util_fd_stdin &&
- return 148
- ble/complete/source/test-limit $((progcomp_read_count++))
- return "$?"
-}
-function ble/complete/progcomp/.compgen-helper-func {
- [[ $comp_func ]] || return 1
- local -a COMP_WORDS
- local COMP_LINE COMP_POINT COMP_CWORD COMP_TYPE COMP_KEY
- ble/complete/progcomp/.compvar-initialize
- local progcomp_read_count=0
- local _ble_builtin_read_hook='ble/complete/progcomp/.check-limits || { builtin read "$@" < /dev/null; return 148; }'
- local fDefault=
- local cmd=${COMP_WORDS[0]} cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
- ble/function#push compopt 'ble/complete/progcomp/compopt "$@"'
- ble/function#push ssh '
- local IFS=$_ble_term_IFS
- if [[ " ${FUNCNAME[*]} " == *" ble/complete/progcomp/.compgen "* ]]; then
- local -a args; args=("$@")
- ble/util/conditional-sync "exec ssh \"\${args[@]}\"" \
- "! ble/complete/check-cancel <&$_ble_util_fd_stdin" 128 progressive-weight:killall
- else
- ble/function#push/call-top "$@"
- fi'
- builtin eval '"$comp_func" "$cmd" "$cur" "$prev"' < /dev/null >&$_ble_util_fd_stdout 2>&$_ble_util_fd_stderr; local ret=$?
- ble/function#pop ssh
- ble/function#pop compopt
- [[ $ret == 124 ]] && progcomp_retry=1
- return 0
-}
-function ble/complete/progcomp/.parse-complete/next {
- if [[ $compdef =~ $rex ]]; then
- builtin eval "arg=$BASH_REMATCH"
- compdef=${compdef:${#BASH_REMATCH}}
- return 0
- elif [[ ${compdef%%' '*} ]]; then
- arg=${compdef%%' '*}
- compdef=${compdef#*' '}
- return 0
- else
- return 1
- fi
-}
-function ble/complete/progcomp/.parse-complete/optarg {
- optarg=
- if ((ic+1<${#arg})); then
- optarg=${arg:ic+1}
- ic=${#arg}
- return 0
- elif [[ $compdef =~ $rex ]]; then
- builtin eval "optarg=$BASH_REMATCH"
- compdef=${compdef:${#BASH_REMATCH}}
- return 0
- else
- return 2
- fi
-}
-function ble/complete/progcomp/.parse-complete {
- compoptions=()
- comp_prog=
- comp_func=
- flag_noquote=
- local compdef=${1#'complete '}
- local arg optarg rex='^([^][*?;&|[:space:]<>()\`$"'\''{}#^!]|\\.|'\''[^'\'']*'\'')+[[:space:]]+' # #D1709 safe (WA gawk 4.0.2)
- while ble/complete/progcomp/.parse-complete/next; do
- case $arg in
- (-*)
- local ic c
- for ((ic=1;ic<${#arg};ic++)); do
- c=${arg:ic:1}
- case "$c" in
- ([abcdefgjksuvE])
- case $c in
- (c) flag_noquote=1 ;;
- (d) ((_ble_bash>=40300)) && flag_noquote=1 ;;
- (f) ((40000<=_ble_bash&&_ble_bash<40200)) && flag_noquote=1 ;;
- esac
- ble/array#push compoptions "-$c" ;;
- ([pr])
- ;; # 無視 (-p 表示 -r 削除)
- ([AGWXPS])
- ble/complete/progcomp/.parse-complete/optarg || break 2
- if [[ $c == A ]]; then
- case $optarg in
- (command) flag_noquote=1 ;;
- (directory) ((_ble_bash>=40300)) && flag_noquote=1 ;;
- (file) ((40000<=_ble_bash&&_ble_bash<40200)) && flag_noquote=1 ;;
- esac
- fi
- ble/array#push compoptions "-$c" "$optarg" ;;
- (o)
- ble/complete/progcomp/.parse-complete/optarg || break 2
- comp_opts=${comp_opts//:"$optarg":/:}$optarg:
- ble/array#push compoptions "-$c" "$optarg" ;;
- (C)
- if ((_ble_bash<40000)); then
- comp_prog=${compdef%' '}
- compdef=
- else
- ble/complete/progcomp/.parse-complete/optarg || break 2
- comp_prog=$optarg
- fi
- ble/array#push compoptions "-$c" ble/complete/progcomp/.compgen-helper-prog ;;
- (F)
- if ((_ble_bash<40000)) && [[ $compdef == *' -C '* ]]; then
- comp_prog=${compdef#*' -C '}
- comp_prog=${comp_prog%' '}
- ble/array#push compoptions '-C' ble/complete/progcomp/.compgen-helper-prog
- comp_func=${compdef%%' -C '*}
- else
- comp_func=${compdef%' '}
- fi
- compdef=
- ble/array#push compoptions "-$c" ble/complete/progcomp/.compgen-helper-func ;;
- (*)
- esac
- done ;;
- (*)
- ;; # 無視
- esac
- done
-}
-function ble/complete/progcomp/.filter-and-split-compgen {
- flag_mandb=
- local sed_script=
- {
- if [[ $comp_opts == *:ble/filter-by-prefix:* ]]; then
- local ret; ble/string#escape-for-sed-regex "$COMPV"; local rex_compv=$ret
- sed_script='!/^'$rex_compv'/d'
- fi
- [[ $use_workaround_for_git ]] &&
- sed_script=${sed_script:+$sed_script;}'s/[[:space:]]\{1,\}$//'
- }
- local out=
- [[ $sed_script ]] && ble/util/assign out 'ble/bin/sed "$sed_script;/^\$/d" <<< "$compgen"'
- [[ $out ]] || out=$compgen
- local require_awk=
- if [[ $comp_opts != *:nosort:* ]]; then
- ble/util/assign out 'ble/bin/sort -u <<< "$out"'
- else
- require_awk=1 # for uniq
- fi
- local -a args_mandb=()
- if [[ $compcmd == "${comp_words[0]}" && $COMPV != [!-]* ]]; then
- if local ret; ble/complete/mandb/generate-cache "$compcmd"; then
- require_awk=1
- args_mandb=(mode=mandb "$ret")
- fi
- fi
- if [[ $require_awk ]]; then
- local awk_script='
- BEGIN { mandb_count = 0; }
- mode == "mandb" {
- name = $0
- sub(/'"$_ble_term_FS"'.*/, "", name);
- if (!mandb[name]) mandb[name] = $0;
- next;
- }
- !hash[$0]++ {
- if (/^$/) next;
- name = $0
- sub(/=$/, "", name);
- if (mandb[name]) {
- mandb_count++;
- print mandb[name];
- next;
- } else if (sub(/^--no-/, "--", name)) {
- if ((entry = mandb[name]) || (entry = mandb[substr(name, 2)])) {
- split(entry, record, FS);
- if ((desc = record[4])) {
- desc = "\033[1mReverse[\033[m " desc " \033[;1m]\033[m";
- if (match($0, /[[:space:]]*[:=[]/)) {
- option = substr($0, 1, RSTART - 1);
- optarg = substr($0, RSTART);
- suffix = substr($0, RSTART, 1);
- if (suffix == "[") suffix = "";
- } else {
- option = $0;
- optarg = "";
- suffix = " ";
- }
- mandb_count++;
- print option FS optarg FS suffix FS desc;
- }
- next;
- }
- }
- print $0;
- }
- END { if (mandb_count) exit 10; }
- '
- ble/util/assign-array "$1" 'ble/bin/awk -F "$_ble_term_FS" "$awk_script" "${args_mandb[@]}" mode=compgen - <<< "$out"'
- (($?==10)) && flag_mandb=1
- else
- ble/string#split-lines "$1" "$out"
- fi
- return 0
-} 2>/dev/null
-function ble/complete/progcomp/.cobraV2.patch {
- local prefix=$cur
- [[ $comps_flags == *v* ]] && prefix=$COMPV
- local unprocessed has_desc=
- unprocessed=()
- local lines line cand desc
- for lines in "${out[@]}"; do
- ble/string#split-lines lines "$lines"
- for line in "${lines[@]}"; do
- if [[ $line == *$'\t'* ]]; then
- cand=${line%%$'\t'*}
- desc=${line#*$'\t'}
- [[ $cand == "$prefix"* ]] || continue
- ble/complete/cand/yield word "$cand" "$desc"
- has_desc=1
- else
- ble/array#push unprocessed "$line"
- fi
- done
- done
- [[ $has_desc ]] && bleopt complete_menu_style=desc
- if ((${#unprocessed[@]})); then
- out=("${unprocessed[@]}")
- ble/function#advice/do
- fi
-}
-function ble/complete/progcomp/.compgen {
- local opts=$1
- local compcmd= is_special_completion=
- local -a alias_args=()
- if [[ :$opts: == *:initial:* ]]; then
- if ((_ble_bash>=50000)); then
- is_special_completion=1
- compcmd='-I'
- else
- compcmd=_InitialWorD_
- fi
- elif [[ :$opts: == *:default:* ]]; then
- if ((_ble_bash>=40100)); then
- builtin complete -p -D &>/dev/null || return 1
- is_special_completion=1
- compcmd='-D'
- else
- builtin complete -p _DefaultCmD_ &>/dev/null || return 1
- compcmd=_DefaultCmD_
- fi
- else
- compcmd=${comp_words[0]}
- fi
- local compdef
- if [[ $is_special_completion ]]; then
- ble/util/assign compdef 'builtin complete -p "$compcmd" 2>/dev/null'
- elif ble/syntax:bash/simple-word/is-simple "$compcmd"; then
- ble/util/assign compdef "builtin complete -p -- $compcmd 2>/dev/null"
- local ret; ble/syntax:bash/simple-word/eval "$compcmd"; compcmd=$ret
- else
- ble/util/assign compdef 'builtin complete -p -- "$compcmd" 2>/dev/null'
- fi
- compdef=${compdef%"${compcmd:-''}"}
- compdef=${compdef%' '}' '
- local comp_prog comp_func compoptions flag_noquote
- ble/complete/progcomp/.parse-complete "$compdef"
- if [[ $comp_func ]]; then
- [[ $comp_func == _fzf_* ]] &&
- ble-import -f contrib/fzf-completion
- if ble/is-function _quote_readline_by_ref; then
- function _quote_readline_by_ref {
- if [[ $1 == \'* ]]; then
- printf -v "$2" %s "${1:1}"
- else
- printf -v "$2" %q "$1"
- [[ ${!2} == \$* ]] && builtin eval "$2=${!2}"
- fi
- }
- ble/function#suppress-stderr _filedir 2>/dev/null
- ble/function#suppress-stderr _find 2>/dev/null
- ble/function#suppress-stderr _scp_remote_files 2>/dev/null
- ble/complete/mandb:_parse_help/inject
- fi
- if [[ $comp_func == __start_* ]]; then
- local target=__${comp_func#__start_}_handle_completion_types
- ble/is-function "$target" &&
- ble/function#advice around "$target" ble/complete/progcomp/.cobraV2.patch
- fi
- ble/function#advice around _dnf_commands_helper '
- ble/util/conditional-sync \
- ble/function#advice/do \
- "! ble/complete/check-cancel <&$_ble_util_fd_stdin" 128 progressive-weight:killall' 2>/dev/null
- fi
- if [[ $comp_prog ]]; then
- if [[ $comp_prog == aws_completer ]]; then
- comp_opts=${comp_opts}ble/no-mark-directories:ble/prog-trim:
- fi
- fi
- ble/complete/check-cancel && return 148
- local compgen compgen_compv=$COMPV
- if [[ ! $flag_noquote && :$comp_opts: != *:noquote:* ]]; then
- local q="'" Q="'\''"
- compgen_compv="'${compgen_compv//$q/$Q}'"
- fi
- local progcomp_prefix= progcomp_retry=
- IFS=$IFS word= ble/util/assign compgen 'builtin compgen "${compoptions[@]}" -- "$compgen_compv" 2>/dev/null'
- if [[ $progcomp_retry && ! $_ble_complete_retry_guard ]]; then
- local _ble_complete_retry_guard=1
- opts=:$opts:
- opts=${opts//:default:/:}
- ble/complete/progcomp/.compgen "$opts"
- return "$?"
- fi
- [[ $compgen ]] || return 1
- local use_workaround_for_git=
- if [[ $comp_func == __git* && $comp_opts == *:nospace:* ]]; then
- use_workaround_for_git=1
- comp_opts=${comp_opts//:nospace:/:}
- fi
- local cands flag_mandb=
- ble/complete/progcomp/.filter-and-split-compgen cands # compgen (comp_opts, etc) -> cands, flag_mandb
- ble/complete/source/test-limit ${#cands[@]} || return 1
- [[ $comp_opts == *:filenames:* && $COMPV == */* ]] && COMP_PREFIX=${COMPV%/*}/
- local old_cand_count=$cand_count
- local action=progcomp "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- if [[ $flag_mandb ]]; then
- local -a entries; entries=("${cands[@]}")
- cands=()
- local fs=$_ble_term_FS has_desc= icand=0 entry
- for entry in "${entries[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- if [[ $entry == -*"$fs"*"$fs"*"$fs"* ]]; then
- local cand=${entry%%"$fs"*}
- ble/complete/cand/yield mandb "$cand" "$entry"
- [[ $entry == *"$fs"*"$fs"*"$fs"?* ]] && has_desc=1
- else
- cands[icand++]=$progcomp_prefix$entry
- fi
- done
- [[ $has_desc ]] && bleopt complete_menu_style=desc
- else
- [[ $progcomp_prefix ]] &&
- if ((_ble_bash>=40300)) && ! shopt -q compat42; then
- cands=("${cands[@]/#/"$progcomp_prefix"}") # WA #D1570 #D1751 safe
- else
- cands=("${cands[@]/#/$progcomp_prefix}") # WA #D1570 #D1738 safe
- fi
- fi
- ble/complete/cand/yield.batch "$action" "$comp_opts"
- [[ $comp_opts == *:plusdirs:* ]] && ble/complete/source:dir
- ((cand_count>old_cand_count))
-}
-function ble/complete/progcomp/.compline-rewrite-command {
- local ocmd=${comp_words[0]}
- [[ $1 != "$ocmd" ]] || (($#>=2)) || return 1
- local IFS=$_ble_term_IFS
- local ins="$*"
- if (($#==0)); then
- local ret; ble/string#ltrim "${comp_line:${#ocmd}}"
- ((comp_point-=${#comp_line}-${#ret}))
- comp_line=$ret
- else
- comp_line=$ins${comp_line:${#ocmd}}
- ((comp_point-=${#ocmd}))
- fi
- ((comp_point<0&&(comp_point=0),comp_point+=${#ins}))
- comp_words=("$@" "${comp_words[@]:1}")
- ((comp_cword&&(comp_cword+=$#-1)))
-}
-function ble/complete/progcomp/.split-alias-words {
- local tail=$1
- local rex_redir='^'$_ble_syntax_bash_RexRedirect
- local rex_word='^'$_ble_syntax_bash_simple_rex_element'+'
- local rex_delim=$'^[\n;|&]'
- local rex_spaces=$'^[ \t]+'
- local rex_misc='^[<>()]+'
- local -a words=()
- while [[ $tail ]]; do
- if [[ $tail =~ $rex_redir && $tail != ['<>']'('* ]]; then
- ble/array#push words "$BASH_REMATCH"
- tail=${tail:${#BASH_REMATCH}}
- elif [[ $tail =~ $rex_word ]]; then
- local w=$BASH_REMATCH
- tail=${tail:${#w}}
- if [[ $tail && $tail != ["$_ble_term_IFS;|&<>()"]* ]]; then
- local s=${tail%%["$_ble_term_IFS"]*}
- tail=${tail:${#s}}
- w=$w$s
- fi
- ble/array#push words "$w"
- elif [[ $tail =~ $rex_delim ]]; then
- words=()
- tail=${tail:${#BASH_REMATCH}}
- elif [[ $tail =~ $rex_spaces ]]; then
- tail=${tail:${#BASH_REMATCH}}
- elif [[ $tail =~ $rex_misc ]]; then
- ble/array#push words "$BASH_REMATCH"
- tail=${tail:${#BASH_REMATCH}}
- else
- local w=${tail%%["$_ble_term_IFS"]*}
- ble/array#push words "$w"
- tail=${tail:${#w}}
- fi
- done
- local i=0 rex_assign='^[a-zA-Z_0-9]+(\['$_ble_syntax_bash_simple_rex_element'*\])?\+?='
- while ((i<${#words[@]})); do
- if [[ ${words[i]} =~ $rex_assign ]]; then
- ((i++))
- elif [[ ${words[i]} =~ $rex_redir && ${words[i]} != ['<>']'('* ]]; then
- ((i+=2))
- else
- break
- fi
- done
- ret=("${words[@]:i}")
-}
-function ble/complete/progcomp {
- local cmd=${1-${comp_words[0]}} opts=$2
- local -a orig_comp_words; orig_comp_words=("${comp_words[@]}")
- local comp_words comp_line=$comp_line comp_point=$comp_point comp_cword=$comp_cword
- comp_words=("$cmd" "${orig_comp_words[@]:1}")
- local orig_qcmds_set=
- local -a orig_qcmds=()
- local -a alias_args=()
- [[ :$opts: == *:__recursive__:* ]] ||
- local alias_checked=' '
- while :; do
- local ret ucmd qcmds
- ucmd=$cmd qcmds=("$cmd")
- if ble/syntax:bash/simple-word/is-simple "$cmd"; then
- if ble/syntax:bash/simple-word/eval "$cmd" noglob &&
- [[ $ret != "$cmd" || ${#ret[@]} -ne 1 ]]; then
- ucmd=${ret[0]} qcmds=()
- local word
- for word in "${ret[@]}"; do
- ble/string#quote-word "$word" quote-empty
- ble/array#push qcmds "$ret"
- done
- else
- ble/string#quote-word "$cmd" quote-empty
- qcmds=("$ret")
- fi
- [[ $cmd == "${orig_comp_words[0]}" ]] &&
- orig_qcmds_set=1 orig_qcmds=("${qcmds[@]}")
- fi
- if ble/is-function "ble/cmdinfo/complete:$ucmd"; then
- ble/complete/progcomp/.compline-rewrite-command "${qcmds[@]}" "${alias_args[@]}"
- "ble/cmdinfo/complete:$ucmd" "$opts"
- return "$?"
- elif [[ $ucmd == */?* ]] && ble/is-function "ble/cmdinfo/complete:${ucmd##*/}"; then
- ble/string#quote-word "${ucmd##*/}"; qcmds[0]=$ret
- ble/complete/progcomp/.compline-rewrite-command "${qcmds[@]}" "${alias_args[@]}"
- "ble/cmdinfo/complete:${ucmd##*/}" "$opts"
- return "$?"
- elif builtin complete -p -- "$ucmd" &>/dev/null; then
- ble/complete/progcomp/.compline-rewrite-command "${qcmds[@]}" "${alias_args[@]}"
- ble/complete/progcomp/.compgen "$opts"
- return "$?"
- elif [[ $ucmd == */?* ]] && builtin complete -p -- "${ucmd##*/}" &>/dev/null; then
- ble/string#quote-word "${ucmd##*/}"; qcmds[0]=$ret
- ble/complete/progcomp/.compline-rewrite-command "${qcmds[@]}" "${alias_args[@]}"
- ble/complete/progcomp/.compgen "$opts"
- return "$?"
- elif
- ble/function#try __load_completion "${ucmd##*/}" &>/dev/null &&
- builtin complete -p -- "${ucmd##*/}" &>/dev/null
- then
- ble/string#quote-word "${ucmd##*/}"; qcmds[0]=$ret
- ble/complete/progcomp/.compline-rewrite-command "${qcmds[@]}" "${alias_args[@]}"
- ble/complete/progcomp/.compgen "$opts"
- return "$?"
- fi
- alias_checked=$alias_checked$cmd' '
- ((_ble_bash<50000)) || shopt -q progcomp_alias || break
- local ret
- ble/alias#expand "$cmd"
- [[ $ret == "$cmd" ]] && break
- ble/complete/progcomp/.split-alias-words "$ret"
- if ((${#ret[@]}==0)); then
- ble/complete/progcomp/.compline-rewrite-command "${alias_args[@]}"
- if ((${#comp_words[@]})); then
- if ((comp_cword==0)); then
- ble/complete/source:command
- else
- ble/complete/progcomp "${comp_words[0]}" "__recursive__:$opts"
- fi
- fi
- return $?
- fi
- [[ $alias_checked != *" $ret "* ]] || break
- cmd=$ret
- ((${#ret[@]}>=2)) &&
- alias_args=("${ret[@]:1}" "${alias_args[@]}")
- done
- comp_words=("${orig_comp_words[@]}")
- [[ $orig_qcmds_set ]] &&
- ble/complete/progcomp/.compline-rewrite-command "${orig_qcmds[@]}"
- ble/complete/progcomp/.compgen "default:$opts"
-}
-_ble_complete_option_chars='_!#$%&:;.,^~|\\?\/*a-zA-Z0-9'
-function ble/complete/action:mandb/initialize {
- ble/complete/action/quote-insert
-}
-function ble/complete/action:mandb/initialize.batch {
- ble/complete/action/quote-insert.batch newline
-}
-function ble/complete/action:mandb/complete {
- ble/complete/action/complete.close-quotation
- local fields
- ble/string#split fields "$_ble_term_FS" "$DATA"
- local tail=${fields[2]}
- [[ $tail == ' ' && $comps_flags == *x* ]] && tail=','
- ble/complete/action/complete.addtail "$tail"
-}
-function ble/complete/action:mandb/init-menu-item {
- local ret; ble/color/face2g argument_option; g=$ret
- local fields
- ble/string#split fields "$_ble_term_FS" "$DATA"
- suffix=${fields[1]}
-}
-function ble/complete/action:mandb/get-desc {
- local fields
- ble/string#split fields "$_ble_term_FS" "$DATA"
- desc=${fields[3]}
-}
-function ble/complete/mandb/load-mandb-conf {
- [[ -s $1 ]] || return 0
- local line words
- while builtin read "${_ble_bash_tmout_wa[@]}" -r line || [[ $line ]]; do
- ble/string#split-words words "${line%%'#'*}"
- case ${words[0]} in
- (MANDATORY_MANPATH)
- [[ -d ${words[1]} ]] &&
- ble/array#push manpath_mandatory "${words[1]}" ;;
- (MANPATH_MAP)
- ble/dict#set manpath_map "${words[1]}" "${words[2]}" ;;
- esac
- done < "$1"
-}
-_ble_complete_mandb_default_manpath=()
-function ble/complete/mandb/initialize-manpath {
- ((${#_ble_complete_mandb_default_manpath[@]})) && return 0
- local manpath
- MANPATH= ble/util/assign manpath 'manpath || ble/bin/man -w' 2>/dev/null
- ble/string#split manpath : "$manpath"
- if ((${#manpath[@]}==0)); then
- local -a manpath_mandatory=()
- builtin eval -- "${_ble_util_dict_declare//NAME/manpath_map}"
- ble/complete/mandb/load-mandb-conf /etc/man_db.conf
- ble/complete/mandb/load-mandb-conf ~/.manpath
- if ((${#manpath_mandatory[@]}==0)); then
- local ret
- ble/complete/util/eval-pathname-expansion '~/*/share/man'
- ble/array#push manpath_mandatory "${ret[@]}"
- ble/complete/util/eval-pathname-expansion '~/@(opt|.opt)/*/share/man'
- ble/array#push manpath_mandatory "${ret[@]}"
- for ret in /usr/local/share/man /usr/local/man /usr/share/man; do
- [[ -d $ret ]] && ble/array#push manpath_mandatory "$ret"
- done
- fi
- builtin eval -- "${_ble_util_dict_declare//NAME/mark}"
- local paths path ret
- ble/string#split paths : "$PATH"
- for path in "${paths[@]}"; do
- [[ -d $path ]] || continue
- [[ $path == *?/ ]] && path=${path%/}
- if ble/dict#get manpath_map "$path"; then
- path=$ret
- else
- path=${path%/bin}/share/man
- fi
- if [[ -d $path ]] && ! ble/set#contains mark "$path"; then
- ble/set#add mark "$path"
- ble/array#push manpath "$path"
- fi
- done
- for path in "${manpath_mandatory[@]}"; do
- if [[ -d $path ]] && ! ble/set#contains mark "$path"; then
- ble/set#add mark "$path"
- ble/array#push manpath "$path"
- fi
- done
- fi
- _ble_complete_mandb_default_manpath=("${manpath[@]}")
-}
-function ble/complete/mandb/search-file/.extract-path {
- local command=$1
- [[ $_ble_complete_mandb_lang ]] &&
- local LC_ALL=$$_ble_complete_mandb_lang
- ble/util/assign path 'ble/bin/man -w "$command"' 2>/dev/null
-}
-ble/function#suppress-stderr ble/complete/mandb/search-file/.extract-path
-function ble/complete/mandb/search-file/.check {
- local path=$1
- if [[ $path && -s $path ]]; then
- ret=$path
- return 0
- else
- return 1
- fi
-}
-function ble/complete/mandb/search-file {
- local command=$1
- local path
- ble/complete/mandb/search-file/.extract-path "$command"
- ble/complete/mandb/search-file/.check "$path" && return
- ble/string#split ret : "$MANPATH"
- ((${#ret[@]})) || ret=('')
- local -a manpath=()
- for path in "${ret[@]}"; do
- if [[ $path ]]; then
- ble/array#push manpath "$path"
- else
- ble/complete/mandb/initialize-manpath
- ble/array#push manpath "${_ble_complete_mandb_default_manpath[@]}"
- fi
- done
- local path
- for path in "${manpath[@]}"; do
- [[ -d $path ]] || continue
- ble/complete/mandb/search-file/.check "$path/man1/$command.1" && return 0
- ble/complete/mandb/search-file/.check "$path/man1/$command.8" && return 0
- if ble/is-function ble/bin/gzip; then
- ble/complete/mandb/search-file/.check "$path/man1/$command.1.gz" && return 0
- ble/complete/mandb/search-file/.check "$path/man1/$command.8.gz" && return 0
- fi
- if ble/is-function ble/bin/bzcat; then
- ble/complete/mandb/search-file/.check "$path/man1/$command.1.bz" && return 0
- ble/complete/mandb/search-file/.check "$path/man1/$command.1.bz2" && return 0
- ble/complete/mandb/search-file/.check "$path/man1/$command.8.bz" && return 0
- ble/complete/mandb/search-file/.check "$path/man1/$command.8.bz2" && return 0
- fi
- if ble/is-function ble/bin/xzcat; then
- ble/complete/mandb/search-file/.check "$path/man1/$command.1.xz" && return 0
- ble/complete/mandb/search-file/.check "$path/man1/$command.8.xz" && return 0
- fi
- if ble/is-function ble/bin/lzcat; then
- ble/complete/mandb/search-file/.check "$path/man1/$command.1.lzma" && return 0
- ble/complete/mandb/search-file/.check "$path/man1/$command.8.lzma" && return 0
- fi
- done
- return 1
-}
-if ble/bin/.freeze-utility-path preconv; then
- function ble/complete/mandb/.preconv { ble/bin/preconv; }
-else
- function ble/complete/mandb/.preconv {
- ble/bin/od -A n -t u1 -v | ble/bin/awk '
- BEGIN {
- ECHAR = 65533; # U+FFFD
- byte = 0;
- for (i = 0; byte < 128; byte++) { mtable[byte] = 0; vtable[byte] = i++; }
- for (i = 0; byte < 192; byte++) { mtable[byte] = 0; vtable[byte] = ECHAR; }
- for (i = 0; byte < 224; byte++) { mtable[byte] = 1; vtable[byte] = i++; }
- for (i = 0; byte < 240; byte++) { mtable[byte] = 2; vtable[byte] = i++; }
- for (i = 0; byte < 248; byte++) { mtable[byte] = 3; vtable[byte] = i++; }
- for (i = 0; byte < 252; byte++) { mtable[byte] = 4; vtable[byte] = i++; }
- for (i = 0; byte < 254; byte++) { mtable[byte] = 5; vtable[byte] = i++; }
- for (i = 0; byte < 256; byte++) { mtable[byte] = 0; vtable[byte] = ECHAR; }
- M = 0; C = 0;
- }
- function put_uchar(uchar) {
- if (uchar < 128)
- printf("%c", uchar);
- else
- printf("\\[u%04X]", uchar);
- }
- function process_byte(byte) {
- if (M) {
- if (128 <= byte && byte < 192) {
- C = C * 64 + byte % 64;
- if (--M == 0) put_uchar(C);
- return;
- } else {
- put_uchar(ECHAR);
- M = 0;
- }
- }
- M = mtable[byte];
- C = vtable[byte];
- if (M == 0) put_uchar(C);
- }
- { for (i = 1; i <= NF; i++) process_byte($i); }
- '
- }
-fi
-_ble_complete_mandb_lang=
-if ble/is-function ble/bin/groff; then
- _ble_complete_mandb_convert_type=man
- function ble/complete/mandb/convert-mandoc {
- if [[ $_ble_util_locale_encoding == UTF-8 ]]; then
- ble/bin/groff -k -Tutf8 -man
- else
- ble/bin/groff -Tascii -man
- fi
- }
- if [[ $OSTYPE == darwin* ]] && ! ble/bin/groff -k -Tutf8 -man &>/dev/null <<< 'α'; then
- if ble/bin/groff -T utf8 -m man &>/dev/null <<< '\[u03B1]'; then
- function ble/complete/mandb/convert-mandoc {
- if [[ $_ble_util_locale_encoding == UTF-8 ]]; then
- ble/complete/mandb/.preconv | ble/bin/groff -T utf8 -m man
- else
- ble/bin/groff -T ascii -m man
- fi
- }
- else
- _ble_complete_mandb_lang=C
- function ble/complete/mandb/convert-mandoc {
- ble/bin/groff -T ascii -m man
- }
- fi
- fi
-elif ble/is-function ble/bin/nroff; then
- _ble_complete_mandb_convert_type=man
- function ble/complete/mandb/convert-mandoc {
- if [[ $_ble_util_locale_encoding == UTF-8 ]]; then
- ble/bin/nroff -Tutf8 -man
- else
- ble/bin/groff -Tascii -man
- fi
- }
-elif ble/is-function ble/bin/mandoc; then
- _ble_complete_mandb_convert_type=mdoc
- function ble/complete/mandb/convert-mandoc {
- ble/bin/mandoc -mdoc
- }
-fi
-function ble/complete/mandb/.generate-cache-from-man {
- ble/is-function ble/bin/man &&
- ble/is-function ble/complete/mandb/convert-mandoc || return 1
- local command=$1
- local ret
- ble/complete/mandb/search-file "$command" || return 1
- local path=$ret
- case $ret in
- (*.gz) ble/bin/gzip -cd "$path" ;;
- (*.bz|*.bz2) ble/bin/bzcat "$path" ;;
- (*.lzma) ble/bin/lzcat "$path" ;;
- (*.xz) ble/bin/xzcat "$path" ;;
- (*) ble/bin/cat "$path" ;;
- esac | ble/bin/awk -v type="$_ble_complete_mandb_convert_type" '
- BEGIN {
- g_keys_count = 0;
- g_desc = "";
- if (type == "man") {
- print ".TH __ble_ignore__ 1 __ble_ignore__ __ble_ignore__";
- print ".ll 9999"
- topic_start = ".TP";
- }
- mode = "begin";
- fmt3_state = "";
- fmt5_state = "";
- fmt6_state = "";
- }
- function output_pair(key, desc) {
- print "";
- print "__ble_key__";
- if (topic_start != "") print topic_start;
- print key;
- print "";
- print "__ble_desc__";
- print "";
- print desc;
- }
- function flush_topic(_, i) {
- if (g_keys_count != 0) {
- for (i = 0; i < g_keys_count; i++)
- output_pair(g_keys[i], g_desc);
- }
- g_keys_count = 0;
- g_desc = "";
- fmt3_flush();
- fmt5_state = "";
- fmt6_flush();
- }
- mode == "begin" && /^\.(Dd|Nm)[[:space:]]/ {
- if (type == "man" && /^\.Dd[[:space:]]+\$Mdoc/) topic_start = "";
- print $0;
- }
- function register_key(key) {
- g_keys[g_keys_count++] = key;
- g_desc = "";
- }
- /^\.ig/ { mode = "ignore"; next; }
- mode == "ignore" {
- if (/^\.\.[[:space:]]*/) mode = "none";
- next;
- }
- {
- sub(/[[:space:]]+$/, "");
- REQ = match($0, /^\.[_[:alnum:]]+/) ? substr($0, 2, RLENGTH - 1) : "";
- }
- REQ ~ /^(S[Ss]|S[Hh]|Pp)$/ { flush_topic(); next; }
- REQ == "PP" {
- flush_topic();
- fmt5_state = "key";
- fmt5_key = "";
- fmt5_desc = "";
- next;
- }
- fmt5_state {
- if (fmt5_state == "key") {
- if (/^\.RS([^_[:alnum:]]|$)/)
- fmt5_state = "desc";
- else if (/^\.RE([^_[:alnum:]]|$)/)
- fmt5_state = "none";
- else
- fmt5_key = (fmt5_key ? "\n" : "") $0;
- } else if (fmt5_state == "desc") {
- if (/^\.RE([^_[:alnum:]]|$)/) {
- register_key(fmt5_key);
- g_desc = fmt5_desc;
- flush_topic();
- fmt5_state = "";
- } else
- fmt5_desc = (fmt5_desc ? "\n" : "") $0;
- }
- }
- REQ == "HP" {
- flush_topic();
- fmt3_state = "key";
- fmt3_key_count = 0;
- fmt3_desc = "";
- next;
- }
- function fmt3_process(_, key) {
- if (REQ == "TP") { fmt3_flush(); return; }
- if (REQ == "PD") return;
- if (fmt3_state == "key") {
- if (REQ == "IP") { fmt3_state = "desc"; return; }
- if (match($0, /( | )[[:space:]]*/)) {
- fmt3_keys[fmt3_key_count++] = substr($0, 1, RSTART - 1);
- fmt3_desc = substr($0, RSTART + RLENGTH);
- fmt3_state = "desc";
- } else {
- fmt3_keys[fmt3_key_count++] = $0;
- }
- } else if (fmt3_state == "desc") {
- if (fmt3_desc != "") fmt3_desc = fmt3_desc "\n";
- fmt3_desc = fmt3_desc $0;
- }
- }
- function fmt3_flush(_, i) {
- if (fmt3_state == "desc" && fmt3_key_count > 0) {
- for (i = 0; i < fmt3_key_count; i++)
- register_key(fmt3_keys[i]);
- g_desc = fmt3_desc;
- }
- fmt3_state = "";
- fmt3_key_count = 0;
- fmt3_desc = "";
- }
- fmt3_state { fmt3_process(); }
- /^\.IP[[:space:]]+".*"([[:space:]]+[0-9]+)?$/ && fmt3_state != "key" {
- fmt6_init();
- fmt4_init();
- next;
- }
- function fmt4_init() {
- if (mode != "fmt4_desc")
- if (!(g_keys_count && g_desc == "")) flush_topic();
- gsub(/^\.IP[[:space:]]+"|"([[:space:]]+[0-9]+)?$/, "");
- register_key($0);
- mode = "fmt4_desc";
- }
- mode == "fmt4_desc" {
- if ($0 == "") { flush_topic(); mode = "none"; next; }
- if (g_keys_count == 1 && g_keys[0] == "\\(bu" && match($0, /^\\fC[^\\]+\\fP( or \\fC[^\\]+\\fP)?/) > 0) {
- _key = substr($0, 1, RLENGTH);
- _desc = substr($0, RLENGTH + 1);
- if (match(_key, / or \\fC[^\\]+\\fP/) > 0)
- _key = substr(_key, 1, RSTART - 1) ", " substr(_key, RSTART + 4);
- g_keys[0] = _key;
- g_desc = _desc;
- next;
- }
- if (REQ == "PD") next;
- if (/^\.IX[[:space:]]+Item[[:space:]]+/) next;
- if (g_desc != "") g_desc = g_desc "\n";
- g_desc = g_desc $0;
- }
- function fmt6_init() {
- fmt6_flush();
- fmt6_state = "desc"
- fmt6_key = $0;
- fmt6_desc = "";
- }
- fmt6_state {
- if (REQ == "IX") {
- fmt6_state = "";
- } else if (REQ == "IP") {
- fmt6_flush();
- } else {
- fmt6_desc = fmt6_desc $0 "\n";
- }
- }
- function fmt6_flush() {
- if (!fmt6_state) return;
- fmt6_state = "";
- if (fmt6_desc)
- output_pair(fmt6_key, fmt6_desc);
- }
- /^\.It Fl([^_[:alnum:]]|$)/ {
- if (g_keys_count && g_desc != "") flush_topic();
- sub(/^\.It Fl/, ".Fl");
- if ($0 ~ / Xo$/) {
- g_current_key = $0;
- mode = "fmt2_keyc"
- } else {
- register_key($0);
- mode = "desc";
- }
- next;
- }
- mode == "fmt2_keyc" {
- if (/^\.PD[[:space:]]*([0-9]+[[:space:]]*)?$/) next;
- g_current_key = g_current_key "\n" $0;
- if (REQ == "Xc") {
- register_key(g_current_key);
- mode = "desc";
- }
- next;
- }
- type == "man" && REQ == "TP" {
- if (g_keys_count && g_desc != "") flush_topic();
- mode = "key1";
- next;
- }
- mode == "key1" {
- if (/^\.PD[[:space:]]*([0-9]+[[:space:]]*)?$/) next;
- register_key($0);
- mode = "desc";
- next;
- }
- mode == "desc" {
- if (REQ == "PD") next;
- if (g_desc != "") g_desc = g_desc "\n";
- g_desc = g_desc $0;
- }
- END { flush_topic(); }
- ' | ble/complete/mandb/convert-mandoc 2>/dev/null | ble/bin/awk -F "$_ble_term_FS" '
- function flush_pair(_, i) {
- if (g_option_count) {
- gsub(/\034/, "\x1b[7m^\\\x1b[27m", g_desc);
- sub(/(\. |; ).*/, ".", g_desc); # Long descriptions are truncated.
- for (i = 0; i < g_option_count; i++)
- print g_options[i] FS g_desc;
- }
- g_option_count = 0;
- g_desc = "";
- }
- function process_key(line, _, n, specs, i, spec, option, optarg, suffix) {
- gsub(/\x1b\[[ -?]*[@-~]/, "", line); # CSI seq
- gsub(/\x1b[ -\/]*[0-~]/, "", line); # ESC seq
- gsub(/.\x08/, "", line); # CHAR BS
- gsub(/\x0E/, "", line); # SO
- gsub(/\x0F/, "", line); # SI
- gsub(/[\x00-\x1F]/, "", line); # Give up all the other control chars
- gsub(/^[[:space:]]*|[[:space:]]*$/, "", line);
- gsub(/[[:space:]]+/, " ", line);
- if (line !~ /^[-+]./) return;
- n = split(line, specs, /,([[:space:]]+|$)| or /);
- prev_optarg = "";
- for (i = n; i > 0; i--) {
- spec = specs[i];
- sub(/,[[:space:]]+$/, "", spec);
- if (spec !~ /^[-+]/ || spec ~ /\034/) { specs[i] = ""; continue; }
- if (match(spec, /\[[:=]?|[:=[:space:]]/)) {
- option = substr(spec, 1, RSTART - 1);
- optarg = substr(spec, RSTART);
- suffix = substr(spec, RSTART + RLENGTH - 1, 1);
- if (suffix == "[") suffix = "";
- prev_optarg = optarg;
- } else {
- option = spec;
- optarg = "";
- suffix = " ";
- if (prev_optarg ~ /[A-Z]|<.+>/) {
- optarg = prev_optarg;
- if (option ~ /^[-+].$/) {
- sub(/^\[=/, "[", optarg);
- sub(/^=/, "", optarg);
- sub(/^[^[:space:][]/, " &", optarg);
- } else {
- if (optarg ~ /^\[[^:=]/)
- sub(/^\[/, "[=", optarg);
- else if (optarg ~ /^[^:=[:space:][]/)
- optarg = " " optarg;
- }
- if (match(optarg, /^\[[:=]?|^[:=[:space:]]/)) {
- suffix = substr(optarg, RSTART + RLENGTH - 1, 1);
- if (suffix == "[") suffix = "";
- }
- }
- }
- specs[i] = option FS optarg FS suffix;
- }
- for (i = 1; i <= n; i++) {
- if (specs[i] == "") continue;
- option = substr(specs[i], 1, index(specs[i], FS) - 1);
- if (!g_hash[option]++)
- g_options[g_option_count++] = specs[i];
- }
- }
- function process_desc(line) {
- gsub(/^[[:space:]]*|[[:space:]]*$/, "", line);
- gsub(/[[:space:]][[:space:]]+/, " ", line);
- if (line == "") {
- if (g_desc != "") return 0;
- return 1;
- }
- if (g_desc != "") g_desc = g_desc " ";
- g_desc = g_desc line;
- return 1;
- }
- sub(/^[[:space:]]*__ble_key__/, "", $0) {
- flush_pair();
- mode = "key";
- if (match($0, /__ble_desc__/) > 0) {
- s_key = substr($0, 1, RSTART - 1);
- s_desc = substr($0, RSTART + RLENGTH);
- process_key(s_key);
- mode = "desc";
- if (!process_desc(s_desc)) mode = "";
- next;
- }
- }
- sub(/^[[:space:]]*__ble_desc__/, "", $0) {
- mode = "desc";
- }
- mode == "key" { process_key($0); }
- mode == "desc" { if (!process_desc($0)) mode = ""; }
- END { flush_pair(); }
- ' | ble/bin/sort -t "$_ble_term_FS" -k 1
-}
-function ble/complete/mandb:help/generate-cache {
- local opts=$1
- local -x cfg_usage= cfg_help=1 cfg_plus= cfg_plus_generate=
- [[ :$opts: == *:mandb-help-usage:* ]] && cfg_usage=1
- [[ :$opts: == *:mandb-usage:* ]] && cfg_usage=1 cfg_help=
- ble/string#match ":$opts:" ':plus-options(=[^:]+)?:' &&
- cfg_plus=1 cfg_plus_generate=${BASH_REMATCH[1]:1}
- local space=$' \t' # for #D1709 (WA gawk 4.0.2)
- local rex_argsep='(\[?[:=]| ?|\[)'
- local rex_option='[-+](,|[^]:='$space',[]+)('$rex_argsep'(<[^<>]+>|\([^()]+\)|[^-[:space:]])[^[:space:]]*)?'
- ble/bin/awk -F "$_ble_term_FS" '
- BEGIN {
- cfg_help = ENVIRON["cfg_help"];
- g_indent = -1;
- g_keys_count = 0;
- g_desc = "";
- cfg_usage = ENVIRON["cfg_usage"];
- g_usage_count = 0;
- cfg_plus_generate = ENVIRON["cfg_plus_generate"];
- cfg_plus = ENVIRON["cfg_plus"] cfg_plus_generate;
- }
- function split_option_optarg_suffix(optspec, _, key, suffix, optarg) {
- if (index(optspec, FS) != 0) return "";
- if ((pos = match(optspec, /'"$rex_argsep"'/)) > 0) {
- key = substr(optspec, 1, pos - 1);
- suffix = substr(optspec, pos + RLENGTH - 1, 1);
- if (suffix == "[") suffix = "";
- optarg = substr(optspec, pos);
- } else {
- key = optspec;
- optarg = "";
- suffix = " ";
- }
- if (key ~ /[^-+'"$_ble_complete_option_chars"']/) return "";
- return key FS optarg FS suffix;
- }
- function print_entry(entry, _, name) {
- name = entry;
- sub(/'"$_ble_term_FS"'.*$/, "", name);
- if (name ~ /^\+/ && !cfg_plus) return;
- if (!g_hash[name]++) # uniq
- print entry;
- }
- {
- gsub(/\x1b\[[ -?]*[@-~]/, ""); # CSI seq
- gsub(/\x1b[ -\/]*[0-~]/, ""); # ESC seq
- gsub(/[\x00-\x1F]/, ""); # Remove all the other C0 chars
- }
- function generate_plus(_, i, n) {
- if (!cfg_plus_generate) return;
- n = length(cfg_plus_generate);
- for (i = 1; i <= n; i++)
- print_entry("+" substr(cfg_plus_generate, i, 1) FS FS FS);
- }
- function parse_usage(line, _, optspec, optspec1, option, optarg, n, i, o) {
- while (match(line, /\[[[:space:]]*([^][]|\[[^][]*\])+[[:space:]]*\]/)) {
- optspec = substr(line, RSTART + 1, RLENGTH - 2);
- line = substr(line, RSTART + RLENGTH);
- while (match(optspec, /([^][|]|\[[^][]*\])+/)) {
- optspec1 = substr(optspec, RSTART, RLENGTH);
- optspec = substr(optspec, RSTART + RLENGTH);
- gsub(/^[[:space:]]+|[[:space:]]+$/, "", optspec1);
- if (match(optspec1, /^[-+][^]:='"$space"'[]+/)) {
- option = substr(optspec1, RSTART, RLENGTH);
- optarg = substr(optspec1, RSTART + RLENGTH);
- n = RLENGTH;
- if (option ~ /^-.*-/) {
- if ((keyinfo = split_option_optarg_suffix(optspec1)) != "")
- g_usage[g_usage_count++] = keyinfo;
- } else {
- o = substr(option, 1, 1);
- for (i = 2; i <= n; i++)
- if ((keyinfo = split_option_optarg_suffix(o substr(option, i, 1) optarg)) != "")
- g_usage[g_usage_count++] = keyinfo;
- }
- }
- }
- }
- }
- function print_usage(_, i) {
- for (i = 0; i < g_usage_count; i++)
- print_entry(g_usage[i] FS);
- }
- cfg_usage {
- if (NR <= 20 && (g_usage_start || $0 ~ /^[a-zA-Z_0-9]|^[^-[:space:]][^[:space:]]*(: |:)/) ) {
- g_usage_start = 1;
- parse_usage($0);
- } else if (/^[[:space:]]*$/)
- cfg_usage = 0;
- }
- function get_indent(text, _, i, n, ret) {
- ret = 0;
- n = length(text);
- for (i = 1; i <= n; i++) {
- c = substr(text, i, 1);
- if (c == " ")
- ret++;
- else if (c == "\t")
- ret = (int(ret / 8) + 1) * 8;
- else
- break;
- }
- return ret;
- }
- function flush_data(_, i) {
- if (g_indent < 0) return;
- for (i = 0; i < g_keys_count; i++)
- print_entry(g_keys[i] FS g_desc);
- g_indent = -1;
- g_keys_count = 0;
- g_desc = "";
- }
- function register_key(keydef, _, key, keyinfo, keys, nkey, i, optarg) {
- if (g_desc != "") flush_data();
- g_indent = get_indent(keydef);
- nkey = 0;
- for (;;) {
- sub(/^,?[[:space:]]+/, "", keydef);
- if (match(keydef, /^'"$rex_option"'/) <= 0) break;
- key = substr(keydef, 1, RLENGTH);
- keydef = substr(keydef, RLENGTH + 1);
- sub(/,$/, "", key);
- keys[nkey++] = key;
- }
- if (nkey >= 2) {
- optarg = "";
- for (i = nkey; --i >= 0; ) {
- if (match(keys[i], /'"$rex_argsep"'/) > 0) {
- optarg = substr(keys[i], RSTART);
- sub(/^[[:space:]]+/, "", optarg);
- if (optarg !~ /[A-Z]|<.+>/) optarg = "";
- } else if (optarg != ""){
- if (keys[i] ~ /^[-+].$/) {
- optarg2 = optarg;
- sub(/^\[=/, "[", optarg2);
- sub(/^=/, "", optarg2);
- sub(/^[^[:space:][]/, " &", optarg2);
- keys[i] = keys[i] optarg2;
- } else {
- optarg2 = optarg;
- if (optarg2 ~ /^\[[^:=]/)
- sub(/^\[/, "[=", optarg2);
- else if (optarg2 ~ /^[^:=[:space:][]/)
- optarg2 = " " optarg2;
- keys[i] = keys[i] optarg2;
- }
- }
- }
- }
- for (i = 0; i < nkey; i++)
- if ((keyinfo = split_option_optarg_suffix(keys[i])) != "")
- g_keys[g_keys_count++] = keyinfo;
- }
- function append_desc(desc) {
- gsub(/^[[:space:]]+|[[:space:]]$/, "", desc);
- if (desc == "") return;
- if (g_desc == "")
- g_desc = desc;
- else
- g_desc = g_desc " " desc;
- }
- cfg_help && match($0, /^[[:space:]]*'"$rex_option"'(,?[[:space:]]+'"$rex_option"')*/) {
- key = substr($0, 1, RLENGTH);
- desc = substr($0, RLENGTH + 1);
- if (desc ~ /^,/) next;
- register_key(key);
- append_desc(desc);
- next;
- }
- g_indent >= 0 {
- sub(/[[:space:]]+$/, "");
- indent = get_indent($0);
- if (indent <= g_indent)
- flush_data();
- else
- append_desc($0);
- }
- END {
- flush_data();
- print_usage();
- generate_plus();
- }
- ' | ble/bin/sort -t "$_ble_term_FS" -k 1
-}
-function ble/complete/mandb:_parse_help/inject {
- ble/is-function _parse_help || return 0
- ble/function#advice before _parse_help 'ble/complete/mandb:_parse_help/generate-cache "${ADVICE_WORDS[1]}" "${ADVICE_WORDS[2]}"'
- ble/function#advice before _longopt 'ble/complete/mandb:_parse_help/generate-cache "${ADVICE_WORDS[1]}"'
- ble/function#advice before _parse_usage 'ble/complete/mandb:_parse_help/generate-cache "${ADVICE_WORDS[1]}" "${ADVICE_WORDS[2]}" usage'
- function ble/complete/mandb:_parse_help/inject { return 0; }
-}
-function ble/string#hash-pjw {
- local size=${2:-32}
- local S=${3:-$(((size+7)/8))} # shift 4
- local C=$((size-2*S)) # co-shift 24
- local M=$(((1<<size-S)-1)) # mask 0x0FFFFFFF
- local N=$(((1<<S)-1<<S)) # mask2 0x000000F0
- ble/util/s2bytes "$1"
- local c h=0
- for c in "${ret[@]}"; do
- ((h=(h<<S)+c,h=(h^h>>C&N)&M))
- done
- ret=$h
-}
-function ble/complete/mandb:_parse_help/generate-cache {
- [[ $_ble_attached ]] || return 0
- local command=$1; [[ $1 == ble*/* ]] || command=${1##*/}
- local ret; ble/string#hash-pjw "${*:2}" 64; local hash=$ret
- local lc_messages=${LC_ALL:-${LC_MESSAGES:-${LANG:-C}}}
- local mandb_cache_dir=$_ble_base_cache/complete.mandb/${lc_messages//'/'/%}
- local subcache; ble/util/sprintf subcache '%s.%014x' "$mandb_cache_dir/_parse_help.d/$command" "$hash"
- [[ -s $subcache && $subcache -nt $_ble_base/lib/core-complete.sh ]] && return 0
- ble/util/mkd "${subcache%/*}"
- if [[ $1 == - ]]; then
- ble/complete/mandb:help/generate-cache "$3"
- else
- local args default_option=--help
- [[ :$3: == *:usage:* ]] && default_option=--usage
- ble/string#split-words args "${2:-$default_option}"
- "$1" "${args[@]}" 2>&1 | ble/complete/mandb:help/generate-cache "$3"
- fi >| "$subcache"
-}
-function ble/complete/mandb/generate-cache {
- local command=${1##*/}
- local lc_messages=${LC_ALL:-${LC_MESSAGES:-${LANG:-C}}}
- local mandb_cache_dir=$_ble_base_cache/complete.mandb/${lc_messages//'/'/%}
- local fcache=$mandb_cache_dir/$command
- local cmdspec_opts; ble/cmdspec/opts#load "$command"
- [[ :$cmdspec_opts: == *:no-options:* ]] && return 1
- if ble/opts#extract-all-optargs "$cmdspec_opts" mandb-help --help; then
- local -a helpspecs; helpspecs=("${ret[@]}")
- local subcache=$mandb_cache_dir/help.d/$command
- if ! [[ -s $subcache && $subcache -nt $_ble_base/lib/core-complete.sh ]]; then
- ble/util/mkd "${subcache%/*}"
- local helpspec
- for helpspec in "${helpspecs[@]}"; do
- if [[ $helpspec == %* ]]; then
- builtin eval -- "${helpspec:1}"
- elif [[ $helpspec == @* ]]; then
- ble/util/print "${helpspec:1}"
- else
- ble/string#split-words helpspec "${helpspec#+}"
- "$command" "${helpspec[@]}" 2>&1
- fi
- done | ble/complete/mandb:help/generate-cache "$cmdspec_opts" >| "$subcache"
- fi
- fi
- if [[ :$cmdspec_opts: != *:mandb-disable-man:* ]] && ble/bin#has "$1"; then
- local subcache=$mandb_cache_dir/man.d/$command
- if ! [[ -s $subcache && $subcache -nt $_ble_base/lib/core-complete.sh ]]; then
- ble/util/mkd "${subcache%/*}"
- ble/complete/mandb/.generate-cache-from-man "$command" >| "$subcache"
- fi
- fi
- local -a subcaches=()
- local subcache update=
- ble/complete/util/eval-pathname-expansion '"$mandb_cache_dir"/_parse_help.d/"$command".??????????????'
- for subcache in "${ret[@]}" "$mandb_cache_dir"/{help,man}.d/"$command"; do
- if [[ -s $subcache && $subcache -nt $_ble_base/lib/core-complete.sh ]]; then
- ble/array#push subcaches "$subcache"
- [[ $fcache -nt $subcache ]] || update=1
- fi
- done
- if [[ $update ]]; then
- local fs=$_ble_term_FS
- ble/bin/awk -F "$_ble_term_FS" '
- BEGIN { plus_count = 0; nodesc_count = 0; }
- $4 == "" {
- if ($1 ~ /^\+/) {
- plus_name[plus_count] = $1;
- plus_entry[plus_count] = $0;
- plus_count++;
- } else {
- nodesc_name[nodesc_count] = $1;
- nodesc_entry[nodesc_count] = $0;
- nodesc_count++;
- }
- next;
- }
- !hash[$1] { hash[$1] = $0; print; }
- END {
- for (i = 0; i < nodesc_count; i++) {
- if (!hash[nodesc_name[i]]) {
- hash[nodesc_name[i]] = nodesc_entry[i];
- print nodesc_entry[i];
- }
- }
- for (i = 0; i < plus_count; i++) {
- name = plus_name[i];
- if (hash[name]) continue;
- split(plus_entry[i], record, FS);
- optarg = record[2];
- suffix = record[3];
- desc = "";
- mname = name;
- sub(/^\+/, "-", mname);
- if (hash[mname]) {
- if (!optarg) {
- split(hash[mname], record, FS);
- optarg = record[2];
- suffix = record[3];
- }
- desc = hash[mname];
- sub(/^[^'$fs']*'$fs'[^'$fs']*'$fs'[^'$fs']*'$fs'/, "", desc);
- if (desc) desc = "\033[1mReverse[\033[m " desc " \033[;1m]\033[m";
- }
- if (!desc) desc = "reverse of \033[4m" mname "\033[m";
- hash[name] = name FS optarg FS suffix FS desc;
- print hash[name];
- }
- }
- ' "${subcaches[@]}" >| "$fcache"
- fi
- ret=$fcache
- [[ -s $fcache ]]
-}
-function ble/complete/mandb/load-cache {
- ret=()
- ble/complete/mandb/generate-cache "$@" &&
- ble/util/mapfile ret < "$ret"
-}
-function ble/complete/source:option/.is-option-context {
- local rexrej rexreq stopat
- ble/progcolor/stop-option#init "$cmdspec_opts"
- if [[ $stopat ]] && ((stopat<=$#)); then
- return 1
- elif [[ ! $rexrej$rexreq ]]; then
- return 0
- fi
- local word ret
- for word; do
- ble/syntax:bash/simple-word/is-simple "$word" &&
- ble/syntax:bash/simple-word/eval "$word" noglob &&
- ble/progcolor/stop-option#test "$ret" &&
- return 1
- done
- return 0
-}
-function ble/complete/source:option {
- local rex='^-[-+'$_ble_complete_option_chars']*$|^\+[_'$_ble_complete_option_chars']*$'
- [[ ! $COMPV || $COMPV =~ $rex ]] || return 0
- local COMPS=$COMPS COMPV=$COMPV
- ble/complete/source/reduce-compv-for-ambiguous-match
- [[ :$comp_type: == *:[maA]:* ]] && local COMP2=$COMP1
- local comp_words comp_line comp_point comp_cword
- ble/syntax:bash/extract-command "$COMP2" || return 1
- local -a prev_args=()
- ((comp_cword>=1)) && prev_args=("${comp_words[@]:1:comp_cword-1}")
- local cmd=${comp_words[0]}
- local alias_checked=' '
- while local ret; ! ble/complete/mandb/load-cache "$cmd"; do
- alias_checked=$alias_checked$cmd' '
- ble/alias#expand "$cmd" || return 1
- local words; ble/string#split-words ret "$ret"; words=("${ret[@]}")
- local iword=0 rex='^[_a-zA-Z][_a-zA-Z0-9]*\+?='
- while [[ ${words[iword]} =~ $rex ]]; do ((iword++)); done
- [[ ${words[iword]} && $alias_checked != *" ${words[iword]} "* ]] || return 1
- prev_args=("${words[@]:iword+1}" "${prev_args[@]}")
- cmd=${words[iret]}
- done
- local -a entries; entries=("${ret[@]}")
- local ret cmdspec_opts=
- ble/syntax:bash/simple-word/is-simple "$cmd" &&
- ble/syntax:bash/simple-word/eval "$cmd" noglob &&
- ble/cmdspec/opts#load "$ret"
- ble/complete/source:option/.is-option-context "${prev_args[@]}" || return 1
- local "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize mandb
- local entry fs=$_ble_term_FS has_desc=
- for entry in "${entries[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) &&
- ble/complete/check-cancel && return 148
- local CAND=${entry%%$_ble_term_FS*}
- [[ $CAND == "$COMPV"* ]] || continue
- ble/complete/cand/yield mandb "$CAND" "$entry"
- [[ $entry == *"$fs"*"$fs"*"$fs"?* ]] && has_desc=1
- done
- [[ $has_desc ]] && bleopt complete_menu_style=desc
-}
-function ble/complete/source:argument/.generate-user-defined-completion {
- shopt -q progcomp || return 1
- [[ :$comp_type: == *:[maA]:* ]] && local COMP2=$COMP1
- local comp_words comp_line comp_point comp_cword
- ble/syntax:bash/extract-command "$COMP2" || return 1
- local forward_words=
- ((comp_cword)) && IFS=' ' builtin eval 'forward_words="${comp_words[*]::comp_cword} "'
- local comp2_in_word=$((comp_point-${#forward_words}))
- local comp1_in_word=$((comp2_in_word-(COMP2-COMP1)))
- if ((comp1_in_word>0)); then
- local w=${comp_words[comp_cword]}
- comp_words=("${comp_words[@]::comp_cword}" "${w::comp1_in_word}" "${w:comp1_in_word}" "${comp_words[@]:comp_cword+1}")
- IFS=' ' builtin eval 'comp_line="${comp_words[*]}"'
- ((comp_cword++,comp_point++))
- ((comp2_in_word=COMP2-COMP1,comp1_in_word=0))
- fi
- if [[ $COMPV && :$comp_type: == *:[maA]:* ]]; then
- local oword=${comp_words[comp_cword]::comp2_in_word} ins
- local ins=; [[ :$comp_type: == *:a:* ]] && ins=${COMPV::1}
- local ret comps_flags= comps_fixed= # referenced in ble/complete/string#escape-for-completion-context
- if [[ $oword ]]; then
- local simple_flags simple_ibrace
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$oword" || return 1
- comps_flags=v$simple_flags
- ((${simple_ibrace%:*})) && comps_fixed=1
- fi
- ble/complete/string#escape-for-completion-context "$ins" c; ins=$ret
- ble/util/unlocal comps_flags comps_fixed
- ((comp_point+=${#ins}))
- comp_words=("${comp_words[@]::comp_cword}" "$oword$ins" "${comp_words[@]:comp_cword+1}")
- IFS=' ' builtin eval 'comp_line="${comp_words[*]}"'
- ((comp2_in_word+=${#ins}))
- fi
- local opts=$1
- if [[ :$opts: == *:initial:* ]]; then
- ble/complete/progcomp/.compgen initial
- else
- ble/complete/progcomp "${comp_words[0]}"
- fi
-}
-function ble/complete/source:argument {
- local comp_opts=:
- ble/complete/source:sabbrev
- if [[ $comps_flags == *f* && $COMPS != *\* && :$comp_type: != *:[maA]:* ]]; then
- local ret simple_flags simple_ibrace
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$COMPS"
- ble/complete/source/eval-simple-word "$ret*" && ((${#ret[*]})) &&
- ble/complete/cand/yield-filenames file "${ret[@]}"
- (($?==148)) && return 148
- fi
- local old_cand_count=$cand_count
- ble/complete/source:argument/.generate-user-defined-completion; local ext=$?
- ((ext==148||cand_count>old_cand_count)) && return "$ext"
- [[ $comp_opts == *:ble/no-default:* ]] && return "$ext"
- ble/complete/source:option; local ext=$?
- ((ext==148||cand_count>old_cand_count&&${#COMPV})) && return "$ext"
- if [[ $comp_opts == *:dirnames:* ]]; then
- ble/complete/source:dir
- else
- ble/complete/source:file
- fi; local ext=$?
- ((ext==148||cand_count>old_cand_count)) && return "$ext"
- if local rex='^/?[-_a-zA-Z0-9.]+[:=]|^-[^-/=:]'; [[ $COMPV =~ $rex ]]; then
- local prefix=$BASH_REMATCH value=${COMPV:${#BASH_REMATCH}}
- local COMP_PREFIX=$prefix
- [[ :$comp_type: != *:[maA]:* && $value =~ ^.+/ ]] &&
- COMP_PREFIX=$prefix${BASH_REMATCH[0]}
- local ret cand "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/source:file/.construct-pathname-pattern "$value"
- ble/complete/util/eval-pathname-expansion "$ret"; (($?==148)) && return 148
- ble/complete/source/test-limit ${#ret[@]} || return 1
- ble/complete/cand/yield.initialize file_rhs
- for cand in "${ret[@]}"; do
- [[ -e $cand || -h $cand ]] || continue
- [[ $FIGNORE ]] && ! ble/complete/.fignore/filter "$cand" && continue
- ble/complete/cand/yield file_rhs "$prefix$cand" "$prefix"
- done
- fi
-}
-function ble/complete/source/compgen {
- [[ $comps_flags == *v* ]] || return 1
- local COMPS=$COMPS COMPV=$COMPV
- ble/complete/source/reduce-compv-for-ambiguous-match
- local compgen_action=$1
- local action=$2
- local data=$3
- local q="'" Q="'\''"
- local compv_quoted="'${COMPV//$q/$Q}'"
- local arr
- ble/util/assign-array arr 'builtin compgen -A "$compgen_action" -- "$compv_quoted"'
- ble/complete/source/test-limit ${#arr[@]} || return 1
- [[ $1 != '=' && ${#arr[@]} == 1 && $arr == "$COMPV" ]] && return 0
- local cand "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- for cand in "${arr[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- ble/complete/cand/yield "$action" "$cand" "$data"
- done
-}
-function ble/complete/source:variable {
- local data=
- case $1 in
- ('=') data=assignment ;;
- ('b') data=braced ;;
- ('a') data=arithmetic ;;
- ('n') data=nosuffix ;;
- ('w'|*) data=word ;;
- esac
- ble/complete/source/compgen variable variable "$data"
-}
-function ble/complete/source:user {
- ble/complete/source/compgen user word
-}
-function ble/complete/source:hostname {
- ble/complete/source/compgen hostname word
-}
-function ble/complete/complete/determine-context-from-opts {
- local opts=$1
- context=syntax
- if local rex=':context=([^:]+):'; [[ :$opts: =~ $rex ]]; then
- local rematch1=${BASH_REMATCH[1]}
- if ble/is-function ble/complete/context:"$rematch1"/generate-sources; then
- context=$rematch1
- else
- ble/util/print "ble/widget/complete: unknown context '$rematch1'" >&2
- fi
- fi
-}
-function ble/complete/context/filter-prefix-sources {
- local -a filtered_sources=()
- local src asrc
- for src in "${sources[@]}"; do
- ble/string#split-words asrc "$src"
- local comp1=${asrc[1]}
- ((comp1<comp_index)) &&
- ble/array#push filtered_sources "$src"
- done
- sources=("${filtered_sources[@]}")
- ((${#sources[@]}))
-}
-function ble/complete/context/overwrite-sources {
- local source_name=$1
- local -a new_sources=()
- local src asrc mark
- for src in "${sources[@]}"; do
- ble/string#split-words asrc "$src"
- [[ ${mark[asrc[1]]} ]] && continue
- ble/array#push new_sources "$source_name ${asrc[1]}"
- mark[asrc[1]]=1
- done
- ((${#new_sources[@]})) ||
- ble/array#push new_sources "$source_name $comp_index"
- sources=("${new_sources[@]}")
-}
-function ble/complete/context:syntax/generate-sources {
- ble/syntax/import
- ble-edit/content/update-syntax
- ble/cmdspec/initialize # load user configruation
- ble/syntax/completion-context/generate "$comp_text" "$comp_index"
- ((${#sources[@]}))
-}
-function ble/complete/context:filename/generate-sources {
- ble/complete/context:syntax/generate-sources || return "$?"
- ble/complete/context/overwrite-sources file
-}
-function ble/complete/context:command/generate-sources {
- ble/complete/context:syntax/generate-sources || return "$?"
- ble/complete/context/overwrite-sources command
-}
-function ble/complete/context:variable/generate-sources {
- ble/complete/context:syntax/generate-sources || return "$?"
- ble/complete/context/overwrite-sources variable
-}
-function ble/complete/context:username/generate-sources {
- ble/complete/context:syntax/generate-sources || return "$?"
- ble/complete/context/overwrite-sources user
-}
-function ble/complete/context:hostname/generate-sources {
- ble/complete/context:syntax/generate-sources || return "$?"
- ble/complete/context/overwrite-sources hostname
-}
-function ble/complete/context:glob/generate-sources {
- comp_type=$comp_type:raw
- ble/complete/context:syntax/generate-sources || return "$?"
- ble/complete/context/overwrite-sources glob
-}
-function ble/complete/source:glob {
- [[ $comps_flags == *v* ]] || return 1
- [[ :$comp_type: == *:[maA]:* ]] && return 1
- local pattern=$COMPV
- ble/complete/source/eval-simple-word "$pattern"; (($?==148)) && return 148
- if ((!${#ret[@]})) && [[ $pattern != *'*' ]]; then
- ble/complete/source/eval-simple-word "$pattern*"; (($?==148)) && return 148
- fi
- local cand action=file "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- for cand in "${ret[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- ble/complete/cand/yield "$action" "$cand"
- done
-}
-function ble/complete/context:dynamic-history/generate-sources {
- comp_type=$comp_type:raw
- ble/complete/context:syntax/generate-sources || return "$?"
- ble/complete/context/overwrite-sources dynamic-history
-}
-function ble/complete/source:dynamic-history {
- [[ $comps_flags == *v* ]] || return 1
- [[ :$comp_type: == *:[maA]:* ]] && return 1
- [[ $COMPV ]] || return 1
- local wordbreaks; ble/complete/get-wordbreaks
- wordbreaks=${wordbreaks//$'\n'}
- local ret; ble/string#escape-for-extended-regex "$COMPV"
- local rex_needle='(^|['$wordbreaks'])'$ret'[^'$wordbreaks']+'
- local rex_wordbreaks='['$wordbreaks']'
- ble/util/assign-array ret 'HISTTIMEFORMAT= builtin history | ble/bin/grep -Eo "$rex_needle" | ble/bin/sed "s/^$rex_wordbreaks//" | ble/bin/sort -u'
- local cand action=literal-word "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- for cand in "${ret[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- ble/complete/cand/yield "$action" "$cand"
- done
-}
-function ble/complete/util/construct-ambiguous-regex {
- local text=$1 fixlen=${2:-1}
- local opt_icase=; [[ :$comp_type: == *:i:* ]] && opt_icase=1
- local -a buff=()
- local i=0 n=${#text} ch=
- for ((i=0;i<n;i++)); do
- ((i>=fixlen)) && ble/array#push buff '.*'
- ch=${text:i:1}
- if [[ $ch == [a-zA-Z] ]]; then
- if [[ $opt_icase ]]; then
- ble/string#toggle-case "$ch"
- ch=[$ch$ret]
- fi
- else
- ble/string#escape-for-extended-regex "$ch"; ch=$ret
- fi
- ble/array#push buff "$ch"
- done
- IFS= builtin eval 'ret="${buff[*]}"'
-}
-function ble/complete/util/construct-glob-pattern {
- local text=$1
- if [[ :$comp_type: == *:i:* ]]; then
- local i n=${#text} c
- local -a buff=()
- for ((i=0;i<n;i++)); do
- c=${text:i:1}
- if [[ $c == [a-zA-Z] ]]; then
- ble/string#toggle-case "$c"
- c=[$c$ret]
- else
- ble/string#escape-for-bash-glob "$c"; c=$ret
- fi
- ble/array#push buff "$c"
- done
- IFS= builtin eval 'ret="${buff[*]}"'
- else
- ble/string#escape-for-bash-glob "$1"
- fi
-}
-function ble/complete/.fignore/prepare {
- _fignore=()
- local i=0 leaf tmp
- ble/string#split tmp ':' "$FIGNORE"
- for leaf in "${tmp[@]}"; do
- [[ $leaf ]] && _fignore[i++]="$leaf"
- done
-}
-function ble/complete/.fignore/filter {
- local pat
- for pat in "${_fignore[@]}"; do
- [[ $1 == *"$pat" ]] && return 1
- done
- return 0
-}
-function ble/complete/candidates/.pick-nearest-sources {
- COMP1= COMP2=$comp_index
- nearest_sources=()
- local -a unused_sources=()
- local src asrc
- for src in "${remaining_sources[@]}"; do
- ble/string#split-words asrc "$src"
- if ((COMP1<asrc[1])); then
- COMP1=${asrc[1]}
- ble/array#push unused_sources "${nearest_sources[@]}"
- nearest_sources=("$src")
- elif ((COMP1==asrc[1])); then
- ble/array#push nearest_sources "$src"
- else
- ble/array#push unused_sources "$src"
- fi
- done
- remaining_sources=("${unused_sources[@]}")
- COMPS=${comp_text:COMP1:COMP2-COMP1}
- comps_flags=
- comps_fixed=
- if [[ ! $COMPS ]]; then
- comps_flags=${comps_flags}v COMPV=
- elif local ret simple_flags simple_ibrace; ble/syntax:bash/simple-word/reconstruct-incomplete-word "$COMPS"; then
- local reconstructed=$ret
- if [[ :$comp_type: == *:raw:* ]]; then
- if ((${simple_ibrace%:*})); then
- COMPV=
- else
- comps_flags=$comps_flags${simple_flags}v
- COMPV=$reconstructed
- fi
- elif ble/complete/source/eval-simple-word "$reconstructed"; local ext=$?; ((ext==148)) && return 148; ((ext==0)); then
- COMPV=("${ret[@]}")
- comps_flags=$comps_flags${simple_flags}v
- if ((${simple_ibrace%:*})); then
- ble/complete/source/eval-simple-word "${reconstructed::${simple_ibrace#*:}}" single; (($?==148)) && return 148
- comps_fixed=${simple_ibrace%:*}:$ret
- comps_flags=${comps_flags}x
- fi
- else
- COMPV=
- comps_flags=$comps_flags${simple_flags}f
- fi
- [[ $COMPS =~ $rex_raw_paramx ]] && comps_flags=${comps_flags}p
- else
- COMPV=
- fi
-}
-function ble/complete/candidates/clear {
- cand_count=0
- cand_cand=()
- cand_word=()
- cand_pack=()
-}
-function ble/complete/candidates/.filter-by-command {
- local command=$1
- local i j=0
- local -a prop=() cand=() word=() show=() data=()
- for ((i=0;i<cand_count;i++)); do
- ((i%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- builtin eval -- "$command" || continue
- cand[j]=${cand_cand[i]}
- word[j]=${cand_word[i]}
- data[j]=${cand_pack[i]}
- ((j++))
- done
- cand_count=$j
- cand_cand=("${cand[@]}")
- cand_word=("${word[@]}")
- cand_pack=("${data[@]}")
-}
-function ble/complete/candidates/.filter-by-regex {
- local rex_filter=$1
- ble/complete/candidates/.filter-by-command '[[ ${cand_cand[i]} =~ $rex_filter ]]'
-}
-function ble/complete/candidates/.filter-by-glob {
- local globpat=$1
- ble/complete/candidates/.filter-by-command '[[ ${cand_cand[i]} == $globpat ]]'
-}
-function ble/complete/candidates/.filter-word-by-prefix {
- local prefix=$1
- ble/complete/candidates/.filter-by-command '[[ ${cand_word[i]} == "$prefix"* ]]'
-}
-function ble/complete/candidates/.initialize-rex_raw_paramx {
- local element=$_ble_syntax_bash_simple_rex_element
- local open_dquot=$_ble_syntax_bash_simple_rex_open_dquot
- rex_raw_paramx='^('$element'*('$open_dquot')?)\$[a-zA-Z_][a-zA-Z_0-9]*$'
-}
-function ble/complete/candidates/filter#init {
- comp_filter_type=$1
- comp_filter_pattern=
- ble/complete/candidates/filter:"$comp_filter_type"/init "$2"
-}
-function ble/complete/candidates/filter#test {
- ble/complete/candidates/filter:"$comp_filter_type"/test "$1"
-}
-function ble/complete/candidates/filter:none/init { ble/complete/candidates/filter:head/init "$@"; }
-function ble/complete/candidates/filter:none/test { true; }
-function ble/complete/candidates/filter:none/count-match-chars { ble/complete/candidates/filter:head/count-match-chars "$@"; }
-function ble/complete/candidates/filter:none/match { ble/complete/candidates/filter:head/match "$@"; }
-function ble/complete/candidates/filter:head/init {
- local ret; ble/complete/util/construct-glob-pattern "$1"
- comp_filter_pattern=$ret*
-}
-function ble/complete/candidates/filter:head/count-match-chars { # unused but for completeness
- local value=$1 compv=$COMPV
- if [[ :$comp_type: == *:i:* ]]; then
- ble/string#tolower "$value"; value=$ret
- ble/string#tolower "$compv"; compv=$ret
- fi
- if [[ $value == "$compv"* ]]; then
- ret=${#compv}
- elif [[ $compv == "$value"* ]]; then
- ret=${#value}
- else
- ret=0
- fi
-}
-function ble/complete/candidates/filter:head/test { [[ $1 == $comp_filter_pattern ]]; }
-function ble/complete/candidates/filter:head/match {
- local needle=$1 text=$2
- if [[ :$comp_type: == *:i:* ]]; then
- ble/string#tolower "$needle"; needle=$ret
- ble/string#tolower "$text"; text=$ret
- fi
- if [[ ! $needle || ! $text ]]; then
- ret=()
- elif [[ $text == "$needle"* ]]; then
- ret=(0 ${#needle})
- return 0
- elif [[ $text == "${needle::${#text}}" ]]; then
- ret=(0 ${#text})
- return 0
- else
- ret=()
- return 1
- fi
-}
-function ble/complete/candidates/filter:substr/init {
- local ret; ble/complete/util/construct-glob-pattern "$1"
- comp_filter_pattern=*$ret*
-}
-function ble/complete/candidates/filter:substr/count-match-chars {
- local value=$1 compv=$COMPV
- if [[ :$comp_type: == *:i:* ]]; then
- ble/string#tolower "$value"; value=$ret
- ble/string#tolower "$compv"; compv=$ret
- fi
- if [[ $value == *"$compv"* ]]; then
- ret=${#compv}
- return 0
- fi
- ble/complete/string#common-suffix-prefix "$value" "$compv"
- ret=${#ret}
-}
-function ble/complete/candidates/filter:substr/test { [[ $1 == $comp_filter_pattern ]]; }
-function ble/complete/candidates/filter:substr/match {
- local needle=$1 text=$2
- if [[ :$comp_type: == *:i:* ]]; then
- ble/string#tolower "$needle"; needle=$ret
- ble/string#tolower "$text"; text=$ret
- fi
- if [[ ! $needle ]]; then
- ret=()
- elif [[ $text == *"$needle"* ]]; then
- text=${text%%"$needle"*}
- local beg=${#text}
- local end=$((beg+${#needle}))
- ret=("$beg" "$end")
- elif ble/complete/string#common-suffix-prefix "$text" "$needle"; ((${#ret})); then
- local end=${#text}
- local beg=$((end-${#ret}))
- ret=("$beg" "$end")
- else
- ret=()
- fi
-}
-function ble/complete/candidates/filter:hsubseq/.determine-fixlen {
- fixlen=${1:-1}
- if [[ $comps_fixed ]]; then
- local compv_fixed_part=${comps_fixed#*:}
- [[ $compv_fixed_part ]] && fixlen=${#compv_fixed_part}
- fi
-}
-function ble/complete/candidates/filter:hsubseq/init {
- local fixlen; ble/complete/candidates/filter:hsubseq/.determine-fixlen "$2"
- local ret; ble/complete/util/construct-ambiguous-regex "$1" "$fixlen"
- comp_filter_pattern=^$ret
-}
-function ble/complete/candidates/filter:hsubseq/count-match-chars {
- local value=$1 compv=$COMPV
- if [[ :$comp_type: == *:i:* ]]; then
- ble/string#tolower "$value"; value=$ret
- ble/string#tolower "$compv"; compv=$ret
- fi
- local fixlen
- ble/complete/candidates/filter:hsubseq/.determine-fixlen "$2"
- [[ $value == "${compv::fixlen}"* ]] || return 1
- value=${value:fixlen}
- local i n=${#COMPV}
- for ((i=fixlen;i<n;i++)); do
- local a=${value%%"${compv:i:1}"*}
- [[ $a == "$value" ]] && { ret=$i; return 0; }
- value=${value:${#a}+1}
- done
- ret=$n
-}
-function ble/complete/candidates/filter:hsubseq/test { [[ $1 =~ $comp_filter_pattern ]]; }
-function ble/complete/candidates/filter:hsubseq/match {
- local needle=$1 text=$2
- if [[ :$comp_type: == *:i:* ]]; then
- ble/string#tolower "$needle"; needle=$ret
- ble/string#tolower "$text"; text=$ret
- fi
- local fixlen; ble/complete/candidates/filter:hsubseq/.determine-fixlen "$3"
- local prefix=${needle::fixlen}
- if [[ $text != "$prefix"* ]]; then
- if [[ $text && $text == "${prefix::${#text}}" ]]; then
- ret=(0 ${#text})
- else
- ret=()
- fi
- return 0
- fi
- local pN=${#text} iN=${#needle}
- local first=1
- ret=()
- while :; do
- if [[ $first ]]; then
- first=
- local p0=0 p=${#prefix} i=${#prefix}
- else
- ((i<iN)) || return 0
- while ((p<pN)) && [[ ${text:p:1} != "${needle:i:1}" ]]; do
- ((p++))
- done
- ((p<pN)) || return 1
- p0=$p
- fi
- while ((i<iN&&p<pN)) && [[ ${text:p:1} == "${needle:i:1}" ]]; do
- ((p++,i++))
- done
- ((p0<p)) && ble/array#push ret "$p0" "$p"
- done
-}
-function ble/complete/candidates/filter:subseq/init {
- [[ $comps_fixed ]] && return 1
- ble/complete/candidates/filter:hsubseq/init "$1" 0
-}
-function ble/complete/candidates/filter:subseq/count-match-chars {
- ble/complete/candidates/filter:hsubseq/count-match-chars "$1" 0
-}
-function ble/complete/candidates/filter:subseq/test { [[ $1 =~ $comp_filter_pattern ]]; }
-function ble/complete/candidates/filter:subseq/match {
- ble/complete/candidates/filter:hsubseq/match "$1" "$2" 0
-}
-function ble/complete/candidates/generate-with-filter {
- local filter_type=$1 opts=$2
- local -a remaining_sources nearest_sources
- remaining_sources=("${sources[@]}")
- local src asrc source
- while ((${#remaining_sources[@]})); do
- nearest_sources=()
- ble/complete/candidates/.pick-nearest-sources; (($?==148)) && return 148
- [[ ! $COMPV && :$opts: == *:no-empty:* ]] && continue
- local comp_filter_type
- local comp_filter_pattern
- ble/complete/candidates/filter#init "$filter_type" "$COMPV" || continue
- for src in "${nearest_sources[@]}"; do
- ble/string#split-words asrc "$src"
- ble/string#split source : "${asrc[0]}"
- local COMP_PREFIX= # 既定値 (yield-candidate で参照)
- ble/complete/source:"${source[@]}"
- ble/complete/check-cancel && return 148
- done
- [[ $comps_fixed ]] &&
- ble/complete/candidates/.filter-word-by-prefix "${COMPS::${comps_fixed%%:*}}"
- ((cand_count)) && return 0
- done
- return 0
-}
-function ble/complete/candidates/comp_type#read-rl-variables {
- ble/util/test-rl-variable completion-ignore-case 0 && comp_type=${comp_type}:i
- ble/util/test-rl-variable visible-stats 0 && comp_type=${comp_type}:vstat
- ble/util/test-rl-variable mark-directories 1 && comp_type=${comp_type}:markdir
- ble/util/test-rl-variable mark-symlinked-directories 1 && comp_type=${comp_type}:marksymdir
- ble/util/test-rl-variable match-hidden-files 1 && comp_type=${comp_type}:match-hidden
- ble/util/test-rl-variable menu-complete-display-prefix 0 && comp_type=${comp_type}:menu-show-prefix
- comp_type=$comp_type:menu-color:menu-color-match
-}
-function ble/complete/candidates/generate {
- local opts=$1
- local flag_force_fignore=
- local flag_source_filter=
- local -a _fignore=()
- if [[ $FIGNORE ]]; then
- ble/complete/.fignore/prepare
- ((${#_fignore[@]})) && shopt -q force_fignore && flag_force_fignore=1
- fi
- local rex_raw_paramx
- ble/complete/candidates/.initialize-rex_raw_paramx
- ble/complete/candidates/comp_type#read-rl-variables
- local cand_iloop=0
- ble/complete/candidates/clear
- ble/complete/candidates/generate-with-filter none "$opts" || return "$?"
- ((cand_count)) && return 0
- if [[ $bleopt_complete_ambiguous && $COMPV ]]; then
- local original_comp_type=$comp_type
- comp_type=${original_comp_type}:m
- ble/complete/candidates/generate-with-filter substr "$opts" || return "$?"
- ((cand_count)) && return 0
- comp_type=${original_comp_type}:a
- ble/complete/candidates/generate-with-filter hsubseq "$opts" || return "$?"
- ((cand_count)) && return 0
- comp_type=${original_comp_type}:A
- ble/complete/candidates/generate-with-filter subseq "$opts" || return "$?"
- ((cand_count)) && return 0
- comp_type=$original_comp_type
- fi
- return 0
-}
-function ble/complete/candidates/determine-common-prefix/.apply-partial-comps {
- local word0=$COMPS word1=$common fixed=
- if [[ $comps_fixed ]]; then
- local fixlen=${comps_fixed%%:*}
- fixed=${word0::fixlen}
- word0=${word0:fixlen}
- word1=${word1:fixlen}
- fi
- local ret spec path spec0 path0 spec1 path1
- ble/complete/source/evaluate-path-spec "$word0"; (($?==148)) && return 148; spec0=("${spec[@]}") path0=("${path[@]}")
- ble/complete/source/evaluate-path-spec "$word1"; (($?==148)) && return 148; spec1=("${spec[@]}") path1=("${path[@]}")
- local i=${#path1[@]}
- while ((i--)); do
- if ble/array#last-index path0 "${path1[i]}"; then
- local elem=${spec1[i]} # workaround bash-3.1 ${#arr[i]} bug
- word1=${spec0[ret]}${word1:${#elem}}
- break
- fi
- done
- common=$fixed$word1
-}
-function ble/complete/candidates/determine-common-prefix {
- local common=${cand_word[0]}
- local clen=${#common}
- if ((cand_count>1)); then
- local unset_nocasematch= flag_tolower=
- if [[ :$comp_type: == *:i:* ]]; then
- if ((_ble_bash<30100)); then
- flag_tolower=1
- ble/string#tolower "$common"; common=$ret
- else
- unset_nocasematch=1
- shopt -s nocasematch
- fi
- fi
- local word loop=0
- for word in "${cand_word[@]:1}"; do
- ((loop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && break
- if [[ $flag_tolower ]]; then
- ble/string#tolower "$word"; word=$ret
- fi
- ((clen>${#word}&&(clen=${#word})))
- while [[ ${word::clen} != "${common::clen}" ]]; do
- ((clen--))
- done
- common=${common::clen}
- done
- [[ $unset_nocasematch ]] && shopt -u nocasematch
- ble/complete/check-cancel && return 148
- [[ $flag_tolower ]] && common=${cand_word[0]::${#common}}
- fi
- if [[ $common != "$COMPS"* && ! ( $cand_count -eq 1 && $comp_type == *:i:* ) ]]; then
- ble/complete/candidates/determine-common-prefix/.apply-partial-comps
- fi
- if ((cand_count>1)) && [[ $common != "$COMPS"* ]]; then
- local common0=$common
- common=$COMPS # 取り敢えず補完挿入をキャンセル
- if [[ :$comp_type: == *:[maAi]:* ]]; then
- local simple_flags simple_ibrace
- if ble/syntax:bash/simple-word/reconstruct-incomplete-word "$common0"; then
- local common_reconstructed=$ret
- local value=$ret filter_type=head
- case :$comp_type: in
- (*:m:*) filter_type=substr ;;
- (*:a:*) filter_type=hsubseq ;;
- (*:A:*) filter_type=subseq ;;
- esac
- local is_processed=
- ble/complete/source/eval-simple-word "$common_reconstructed" single; local ext=$?
- ((ext==148)) && return 148
- if ((ext==0)) && ble/complete/candidates/filter:"$filter_type"/count-match-chars "$ret"; then
- if [[ $filter_type == head ]] && ((ret<${#COMPV})); then
- is_processed=1
- [[ $bleopt_complete_allow_reduction ]] && common=$common0
- elif ((ret)); then
- is_processed=1
- ble/string#escape-for-bash-specialchars "${COMPV:ret}" c
- common=$common0$ret
- fi
- fi
- if [[ ! $is_processed ]] &&
- local notilde=\'\' &&
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$COMPS" &&
- ble/syntax:bash/simple-word/eval "$notilde$ret" noglob &&
- local compv_notilde=$ret &&
- ble/syntax:bash/simple-word/eval "$notilde$common_reconstructed" noglob &&
- local commonv_notilde=$ret &&
- COMPV=$compv_notilde ble/complete/candidates/filter:"$filter_type"/count-match-chars "$commonv_notilde"
- then
- if [[ $filter_type == head ]] && ((ret<${#COMPV})); then
- is_processed=1
- [[ $bleopt_complete_allow_reduction ]] && common=$common0
- elif ((ret)); then
- is_processed=1
- ble/string#escape-for-bash-specialchars "${compv_notilde:ret}" TG
- common=$common0$ret
- fi
- fi
- [[ $is_processed ]] || common=$common0$COMPS
- fi
- else
- if ble/syntax:bash/simple-word/is-simple-or-open-simple "$common"; then
- local flag_reduction=
- if [[ $bleopt_complete_allow_reduction ]]; then
- flag_reduction=1
- else
- local simple_flags simple_ibrace
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$common0" &&
- ble/complete/source/eval-simple-word "$ret" single &&
- [[ $ret == "$COMPV"* ]] &&
- flag_reduction=1
- (($?==148)) && return 148
- fi
- [[ $flag_reduction ]] && common=$common0
- fi
- fi
- fi
- ret=$common
-}
-_ble_complete_menu_active=
-_ble_complete_menu_style=
-_ble_complete_menu0_beg=
-_ble_complete_menu0_end=
-_ble_complete_menu0_str=
-_ble_complete_menu_common_part=
-_ble_complete_menu0_comp=()
-_ble_complete_menu0_pack=()
-_ble_complete_menu_comp=()
-function ble/complete/menu-complete.class/render-item {
- local opts=$2
- if [[ :$opts: == *:selected:* ]]; then
- local COMP1=${_ble_complete_menu_comp[0]}
- local COMP2=${_ble_complete_menu_comp[1]}
- local COMPS=${_ble_complete_menu_comp[2]}
- local COMPV=${_ble_complete_menu_comp[3]}
- local comp_type=${_ble_complete_menu_comp[4]}
- local comps_flags=${_ble_complete_menu0_comp[5]}
- local comps_fixed=${_ble_complete_menu0_comp[6]}
- local menu_common_part=$_ble_complete_menu_common_part
- fi
- local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
- ble/complete/cand/unpack "$1"
- local prefix_len=$PREFIX_LEN
- [[ :$comp_type: == *:menu-show-prefix:* ]] && prefix_len=0
- local filter_target=${CAND:prefix_len}
- if [[ ! $filter_target ]]; then
- ret=
- return 0
- fi
- local g=0 show=$filter_target suffix= prefix=
- ble/function#try ble/complete/action:"$ACTION"/init-menu-item
- local g0=$g; [[ :$comp_type: == *:menu-color:* ]] || g0=0
- local m
- if [[ :$comp_type: == *:menu-color-match:* && $_ble_complete_menu_common_part && $show == *"$filter_target"* ]]; then
- local filter_type=head
- case :$comp_type: in
- (*:m:*) filter_type=substr ;;
- (*:a:*) filter_type=hsubseq ;;
- (*:A:*) filter_type=subseq ;;
- esac
- local needle=${_ble_complete_menu_common_part:prefix_len}
- ble/complete/candidates/filter:"$filter_type"/match "$needle" "$filter_target"; m=("${ret[@]}")
- if [[ $show != "$filter_target" ]]; then
- local show_prefix=${show%%"$filter_target"*}
- local offset=${#show_prefix}
- local i n=${#m[@]}
- for ((i=0;i<n;i++)); do ((m[i]+=offset)); done
- fi
- else
- m=()
- fi
- local sgrN0= sgrN1= sgrB0= sgrB1=
- [[ :$opts: == *:selected:* ]] && ((g0^=_ble_color_gflags_Revert))
- ret=${_ble_color_g2sgr[g=g0]}
- [[ $ret ]] || ble/color/g2sgr "$g"; sgrN0=$ret
- ret=${_ble_color_g2sgr[g=g0^_ble_color_gflags_Revert]}
- [[ $ret ]] || ble/color/g2sgr "$g"; sgrN1=$ret
- if ((${#m[@]})); then
- ret=${_ble_color_g2sgr[g=g0|_ble_color_gflags_Bold]}
- [[ $ret ]] || ble/color/g2sgr "$g"; sgrB0=$ret
- ret=${_ble_color_g2sgr[g=(g0|_ble_color_gflags_Bold)^_ble_color_gflags_Revert]}
- [[ $ret ]] || ble/color/g2sgr "$g"; sgrB1=$ret
- fi
- local out= flag_overflow= p0=0
- if [[ $prefix ]]; then
- ble/canvas/trace-text "$prefix" nonewline || flag_overflow=1
- out=$out$_ble_term_sgr0$ret
- fi
- if ((${#m[@]})); then
- local i iN=${#m[@]} p p0=0 out=
- for ((i=0;i<iN;i++)); do
- ((p=m[i]))
- if ((p0<p)); then
- if ((i%2==0)); then
- local sgr0=$sgrN0 sgr1=$sgrN1
- else
- local sgr0=$sgrB0 sgr1=$sgrB1
- fi
- ble/canvas/trace-text "${show:p0:p-p0}" nonewline:external-sgr || flag_overflow=1
- out=$out$sgr0$ret
- fi
- p0=$p
- done
- fi
- if ((p0<${#show})); then
- local sgr0=$sgrN0 sgr1=$sgrN1
- ble/canvas/trace-text "${show:p0}" nonewline:external-sgr || flag_overflow=1
- out=$out$sgr0$ret
- fi
- if [[ $suffix ]]; then
- ble/canvas/trace-text "$suffix" nonewline || flag_overflow=1
- out=$out$_ble_term_sgr0$ret
- fi
- ret=$out$_ble_term_sgr0
- [[ ! $flag_overflow ]]
-}
-function ble/complete/menu-complete.class/get-desc {
- local item=$1
- local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
- ble/complete/cand/unpack "$item"
- desc="$desc_sgrt(action:$ACTION)$desc_sgr0"
- ble/function#try ble/complete/action:"$ACTION"/get-desc
-}
-function ble/complete/menu-complete.class/onselect {
- local nsel=$1 osel=$2
- local insert=${_ble_complete_menu_original:-${_ble_complete_menu_comp[2]}}
- if ((nsel>=0)); then
- local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
- ble/complete/cand/unpack "${_ble_complete_menu_items[nsel]}"
- insert=$INSERT
- fi
- ble-edit/content/replace-limited "$_ble_complete_menu0_beg" "$_ble_edit_ind" "$insert"
- ((_ble_edit_ind=_ble_complete_menu0_beg+${#insert}))
-}
-function ble/complete/menu/clear {
- if [[ $_ble_complete_menu_active ]]; then
- _ble_complete_menu_active=
- ble/complete/menu#clear
- [[ $_ble_highlight_layer_menu_filter_beg ]] &&
- ble/textarea#invalidate str # layer:menu_filter 解除 (#D0995)
- fi
- return 0
-}
-blehook widget_bell+=ble/complete/menu/clear
-blehook history_onleave+=ble/complete/menu/clear
-function ble/complete/menu/get-footprint {
- footprint=$_ble_edit_ind:$_ble_edit_mark_active:${_ble_edit_mark_active:+$_ble_edit_mark}:$_ble_edit_overwrite_mode:$_ble_edit_str
-}
-function ble/complete/menu/show {
- local opts=$1
- if [[ :$opts: == *:load-filtered-data:* ]]; then
- local COMP1=${_ble_complete_menu_comp[0]}
- local COMP2=${_ble_complete_menu_comp[1]}
- local COMPS=${_ble_complete_menu_comp[2]}
- local COMPV=${_ble_complete_menu_comp[3]}
- local comp_type=${_ble_complete_menu_comp[4]}
- local comps_flags=${_ble_complete_menu0_comp[5]}
- local comps_fixed=${_ble_complete_menu0_comp[6]}
- local cand_pack; cand_pack=("${_ble_complete_menu_items[@]}")
- local menu_common_part=$_ble_complete_menu_common_part
- fi
- local menu_style=$bleopt_complete_menu_style
- [[ :$opts: == *:filter:* && $_ble_complete_menu_style ]] &&
- menu_style=$_ble_complete_menu_style
- local menu_items; menu_items=("${cand_pack[@]}")
- _ble_complete_menu_common_part=$menu_common_part
- local menu_class=ble/complete/menu-complete.class menu_param=
- local menu_opts=$opts
- [[ :$comp_type: == *:sync:* ]] && menu_opts=$menu_opts:sync
- ble/complete/menu#construct "$menu_opts" || return "$?"
- ble/complete/menu#show
- if [[ :$opts: == *:menu-source:* ]]; then
- local left0=${_ble_complete_menu0_str::_ble_complete_menu0_end}
- local left1=${_ble_edit_str::_ble_edit_ind}
- local ret; ble/string#common-prefix "$left0" "$left1"; left0=$ret
- local right0=${_ble_complete_menu0_str:_ble_complete_menu0_end}
- local right1=${_ble_edit_str:_ble_edit_ind}
- local ret; ble/string#common-suffix "$right0" "$right1"; right0=$ret
- local footprint; ble/complete/menu/get-footprint
- _ble_complete_menu0_str=$left0$right0
- _ble_complete_menu0_end=${#left0}
- _ble_complete_menu_footprint=$footprint
- elif [[ :$opts: != *:filter:* ]]; then
- local beg=$COMP1 end=$_ble_edit_ind # COMP2 でなく補完挿入後の位置
- local str=$_ble_edit_str
- [[ $_ble_decode_keymap == auto_complete ]] &&
- str=${str::_ble_edit_ind}${str:_ble_edit_mark}
- local footprint; ble/complete/menu/get-footprint
- _ble_complete_menu_active=1
- _ble_complete_menu_style=$menu_style
- _ble_complete_menu0_beg=$beg
- _ble_complete_menu0_end=$end
- _ble_complete_menu0_str=$str
- _ble_complete_menu0_comp=("$COMP1" "$COMP2" "$COMPS" "$COMPV" "$comp_type" "$comps_flags" "$comps_fixed")
- _ble_complete_menu0_pack=("${cand_pack[@]}")
- _ble_complete_menu_selected=-1
- _ble_complete_menu_comp=("$COMP1" "$COMP2" "$COMPS" "$COMPV" "$comp_type")
- _ble_complete_menu_footprint=$footprint
- fi
- return 0
-}
-function ble/complete/menu/redraw {
- if [[ $_ble_complete_menu_active ]]; then
- ble/complete/menu#show
- fi
-}
-function ble/complete/menu/get-active-range {
- [[ $_ble_complete_menu_active ]] || return 1
- local str=${1-$_ble_edit_str} ind=${2-$_ble_edit_ind}
- local mbeg=$_ble_complete_menu0_beg
- local mend=$_ble_complete_menu0_end
- local left=${_ble_complete_menu0_str::mend}
- local right=${_ble_complete_menu0_str:mend}
- if [[ ${str::_ble_edit_ind} == "$left"* && ${str:_ble_edit_ind} == *"$right" ]]; then
- ((beg=mbeg,end=${#str}-${#right}))
- return 0
- else
- ble/complete/menu/clear
- return 1
- fi
-}
-function ble/complete/menu/generate-candidates-from-menu {
- COMP1=${_ble_complete_menu_comp[0]}
- COMP2=${_ble_complete_menu_comp[1]}
- COMPS=${_ble_complete_menu_comp[2]}
- COMPV=${_ble_complete_menu_comp[3]}
- comp_type=${_ble_complete_menu_comp[4]}
- comps_flags=${_ble_complete_menu0_comp[5]}
- comps_fixed=${_ble_complete_menu0_comp[6]}
- cand_count=${#_ble_complete_menu_items[@]}
- cand_cand=() cand_word=() cand_pack=()
- local pack "${_ble_complete_cand_varnames[@]/%/=}" # #D1570 WA checked
- for pack in "${_ble_complete_menu_items[@]}"; do
- ble/complete/cand/unpack "$pack"
- ble/array#push cand_cand "$CAND"
- ble/array#push cand_word "$INSERT"
- ble/array#push cand_pack "$pack"
- done
- ((cand_count))
-}
-function ble/complete/generate-candidates-from-opts {
- local opts=$1
- local context; ble/complete/complete/determine-context-from-opts "$opts"
- comp_type=
- [[ :$opts: == *:auto_menu:* ]] && comp_type=auto_menu
- local comp_text=$_ble_edit_str comp_index=$_ble_edit_ind
- local sources
- ble/complete/context:"$context"/generate-sources "$comp_text" "$comp_index" || return "$?"
- ble/complete/candidates/generate "$opts"
-}
-function ble/complete/insert {
- local insert_beg=$1 insert_end=$2
- local insert=$3 suffix=$4
- local original_text=${_ble_edit_str:insert_beg:insert_end-insert_beg}
- local ret
- local insert_replace=
- if [[ $insert == "$original_text"* ]]; then
- insert=${insert:insert_end-insert_beg}
- ((insert_beg=insert_end))
- else
- ble/string#common-prefix "$insert" "$original_text"
- if [[ $ret ]]; then
- insert=${insert:${#ret}}
- ((insert_beg+=${#ret}))
- fi
- fi
- if ble/util/test-rl-variable skip-completed-text; then
- if [[ $insert ]]; then
- local right_text=${_ble_edit_str:insert_end}
- right_text=${right_text%%[$IFS]*}
- if ble/string#common-prefix "$insert" "$right_text"; [[ $ret ]]; then
- ((insert_end+=${#ret}))
- elif ble/complete/string#common-suffix-prefix "$insert" "$right_text"; [[ $ret ]]; then
- ((insert_end+=${#ret}))
- fi
- fi
- if [[ $suffix ]]; then
- local right_text=${_ble_edit_str:insert_end}
- if ble/string#common-prefix "$suffix" "$right_text"; [[ $ret ]]; then
- ((insert_end+=${#ret}))
- elif ble/complete/string#common-suffix-prefix "$suffix" "$right_text"; [[ $ret ]]; then
- ((insert_end+=${#ret}))
- fi
- fi
- fi
- local ins=$insert$suffix
- ble/widget/.replace-range "$insert_beg" "$insert_end" "$ins"
- ((_ble_edit_ind=insert_beg+${#ins},
- _ble_edit_ind>${#_ble_edit_str}&&
- (_ble_edit_ind=${#_ble_edit_str})))
-}
-function ble/complete/insert-common {
- local ret
- ble/complete/candidates/determine-common-prefix; (($?==148)) && return 148
- local insert=$ret suffix=
- local insert_beg=$COMP1 insert_end=$COMP2
- local insert_flags=
- [[ $insert == "$COMPS"* ]] || insert_flags=r
- if ((cand_count==1)); then
- local ACTION=${cand_pack[0]%%:*}
- if ble/is-function ble/complete/action:"$ACTION"/complete; then
- local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
- ble/complete/cand/unpack "${cand_pack[0]}"
- ble/complete/action:"$ACTION"/complete
- (($?==148)) && return 148
- fi
- else
- insert_flags=${insert_flags}m
- fi
- local do_insert=1
- if ((cand_count>1)) && [[ $insert_flags == *r* ]]; then
- if [[ :$comp_type: != *:[maAi]:* ]]; then
- do_insert=
- fi
- elif [[ $insert$suffix == "$COMPS" ]]; then
- do_insert=
- fi
- if [[ $do_insert ]]; then
- ble/complete/insert "$insert_beg" "$insert_end" "$insert" "$suffix"
- blehook/invoke complete_insert
- fi
- if [[ $insert_flags == *m* ]]; then
- local menu_common_part=$COMPV
- local ret simple_flags simple_ibrace
- if ble/syntax:bash/simple-word/reconstruct-incomplete-word "$insert"; then
- ble/complete/source/eval-simple-word "$ret" single
- (($?==148)) && return 148
- menu_common_part=$ret
- fi
- ble/complete/menu/show "$menu_show_opts" || return "$?"
- elif [[ $insert_flags == *n* ]]; then
- ble/widget/complete show_menu:regenerate || return "$?"
- else
- _ble_complete_state=complete
- ble/complete/menu/clear
- fi
- return 0
-}
-function ble/complete/insert-all {
- local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
- local pack beg=$COMP1 end=$COMP2 insert= suffix= insert_flags= index=0
- for pack in "${cand_pack[@]}"; do
- ble/complete/cand/unpack "$pack"
- insert=$INSERT suffix= insert_flags=
- if ble/is-function ble/complete/action:"$ACTION"/complete; then
- ble/complete/action:"$ACTION"/complete
- (($?==148)) && return 148
- fi
- [[ $suffix != *' ' ]] && suffix="$suffix "
- ble/complete/insert "$beg" "$end" "$insert" "$suffix"
- blehook/invoke complete_insert
- beg=$_ble_edit_ind end=$_ble_edit_ind
- ((index++))
- done
- _ble_complete_state=complete
- ble/complete/menu/clear
- return 0
-}
-function ble/complete/insert-braces/.compose {
- if ble/bin/awk.supports-null-record-separator; then
- local printf_format='%s\0' RS='"\0"'
- else
- local printf_format='%s\x1E' RS='"\x1E"'
- fi
- local q=\'
- local -x rex_atom='^(\\.|[0-9]+|.)' del_close= del_open= quote_type=
- local -x COMPS=$COMPS
- if [[ :$comp_type: != *:[maAi]:* ]]; then
- local rex_brace='[,{}]|\{[-a-zA-Z0-9]+\.\.[-a-zA-Z0-9]+\}'
- case $comps_flags in
- (*S*) rex_atom='^('$q'(\\'$q'|'$rex_brace')'$q'|[0-9]+|.)' # '...'
- del_close=\' del_open=\' quote_type=S ;;
- (*E*) rex_atom='^(\\.|'$q'('$rex_brace')\$'$q'|[0-9]+|.)' # $'...'
- del_close=\' del_open=\$\' quote_type=E ;;
- (*[DI]*) rex_atom='^(\\[\"$`]|"('$rex_brace')"|[0-9]+|.)' # "...", $"..."
- del_close=\" del_open=\" quote_type=D ;;
- esac
- fi
- printf "$printf_format" "$@" | ble/bin/awk '
- function starts_with(str, head) {
- return substr(str, 1, length(head)) == head;
- }
- BEGIN {
- RS = '"$RS"';
- rex_atom = ENVIRON["rex_atom"];
- del_close = ENVIRON["del_close"];
- del_open = ENVIRON["del_open"];
- quote_type = ENVIRON["quote_type"];
- COMPS = ENVIRON["COMPS"];
- BRACE_OPEN = del_close "{" del_open;
- BRACE_CLOS = del_close "}" del_open;
- }
- function to_atoms(str, arr, _, chr, atom, level, count, rex) {
- count = 0;
- while (match(str, rex_atom) > 0) {
- chr = substr(str, 1, RLENGTH);
- str = substr(str, RLENGTH + 1);
- if (chr == BRACE_OPEN) {
- atom = chr;
- level = 1;
- while (match(str, rex_atom) > 0) {
- chr = substr(str, 1, RLENGTH);
- str = substr(str, RLENGTH + 1);
- atom = atom chr;
- if (chr == BRACE_OPEN)
- level++;
- else if (chr == BRACE_CLOS && --level==0)
- break;
- }
- } else {
- atom = chr;
- }
- arr[count++] = atom;
- }
- return count;
- }
- function remove_empty_quote(str, _, rex_quote_first, rex_quote, out, empty, m) {
- if (quote_type == "S" || quote_type == "E") {
- rex_quote_first = "^[^'$q']*'$q'";
- rex_quote = "'$q'[^'$q']*'$q'|(\\\\.|[^'$q'])+";
- } else if (quote_type == "D") {
- rex_quote_first = "^[^\"]*\"";
- rex_quote = "\"([^\\\"]|\\\\.)*\"|(\\\\.|[^\"])+";
- } else return str;
- empty = del_open del_close;
- out = "";
- if (starts_with(str, COMPS)) {
- out = COMPS;
- str = substr(str, length(COMPS) + 1);
- if (match(str, rex_quote_first) > 0) {
- out = out substr(str, 1, RLENGTH);
- str = substr(str, RLENGTH + 1);
- }
- }
- while (match(str, rex_quote) > 0) {
- m = substr(str, 1, RLENGTH);
- if (m != empty) out = out m;
- str = substr(str, RLENGTH + 1);
- }
- if (str == del_open)
- return out;
- else
- return out str del_close;
- }
- function zpad(value, width, _, wpad, i, pad) {
- wpad = width - length(value);
- pad = "";
- for (i = 0; i < wpad; i++) pad = "0" pad;
- if (value < 0)
- return "-" pad (-value);
- else
- return pad value;
- }
- function zpad_remove(value) {
- if (value ~ /^0+$/)
- value = "0";
- else if (value ~ /^-/)
- sub(/^-0+/, "-", value);
- else
- sub(/^0+/, "", value);
- return value;
- }
- function zpad_a2i(text) {
- sub(/^-0+/, "-", text) || sub(/^0+/, "", text);
- return 0 + text;
- }
- function range_contract(arr, len, _, i, value, alpha, lower, upper, keys, ikey, dict, b, e, beg, end, tmp) {
- lower = "abcdefghijklmnopqrstuvwxyz";
- upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- for (i = 0; i < len; i++) {
- value = arr[i];
- if (dict[value]) {
- dict[value]++;
- } else {
- keys[ikey++] = value;
- dict[value] = 1;
- }
- }
- len = 0;
- for (i = 0; i < ikey; i++) {
- while (dict[value = keys[i]]--) {
- if (value ~ /^([a-zA-Z])$/) {
- alpha = (value ~ /^[a-z]$/) ? lower : upper;
- beg = end = value;
- b = e = index(alpha, value);
- while (b > 1 && dict[tmp = substr(alpha, b - 1, 1)]) {
- dict[beg = tmp]--;
- b--;
- }
- while (e < 26 && dict[tmp = substr(alpha, e + 1, 1)]) {
- dict[end = tmp]--;
- e++;
- }
- if (e == b) {
- arr[len++] = beg;
- } else if (e == b + 1) {
- arr[len++] = beg;
- arr[len++] = end;
- } else {
- arr[len++] = del_close "{" beg ".." end "}" del_open;
- }
- } else if (value ~ /^(0+|-?0*[1-9][0-9]*)$/) {
- beg = end = value;
- b = e = zpad_a2i(value);
- wmax = wmin = length(value);
- if (value ~ /^(0|-?[1-9][0-9]*)$/) {
- while (dict[b - 1]) dict[--b]--;
- while (dict[e + 1]) dict[++e]--;
- tmp = length(beg = "" b);
- if (tmp < wmin) wmin = tmp;
- else if (tmp > wmax) wmax = tmp;
- tmp = length(end = "" e);
- if (tmp < wmin) wmin = tmp;
- else if (tmp > wmax) wmax = tmp;
- }
- if (wmax == wmin) {
- while (length(tmp = zpad(b - 1, wmin)) == wmin && dict[tmp]) { dict[tmp]--; --b; }
- while (length(tmp = zpad(e + 1, wmin)) == wmin && dict[tmp]) { dict[tmp]--; ++e; }
- beg = zpad(b, wmin);
- end = zpad(e, wmin);
- }
- if (e == b) {
- arr[len++] = beg;
- } else if (e == b + 1) {
- arr[len++] = beg;
- arr[len++] = end;
- } else if (b < 0 && e < 0) {
- arr[len++] = del_close "-{" substr(end, 2) ".." substr(beg, 2) "}" del_open;
- } else {
- arr[len++] = del_close "{" beg ".." end "}" del_open;
- }
- } else {
- arr[len++] = value;
- }
- }
- }
- return len;
- }
- function simple_brace(arr, len, _, ret, i) {
- if (len == 0) return "";
- len = range_contract(arr, len);
- if (len == 1) return arr[0];
- ret = BRACE_OPEN arr[0];
- for (i = 1; i < len; i++)
- ret = ret del_close "," del_open arr[i];
- return ret BRACE_CLOS;
- }
- function rfrag_strlen_common(a, b, _, la, lb, tmp, i, n) {
- ret = 0;
- alen = to_atoms(a, abuf);
- blen = to_atoms(b, bbuf);
- while (alen > 0 && blen > 0) {
- if (abuf[alen - 1] != bbuf[blen - 1]) break;
- ret += length(abuf[alen - 1]);
- alen--;
- blen--;
- }
- return ret;
- }
- function rfrag_get_level(str, _, len, i, rfrag0, rfrag0len, rfrag1) {
- len = length(str);
- rfrag_matching_offset = len;
- for (i = 0; i < rfrag_depth - 1; i++) {
- rfrag0 = rfrag[i];
- rfrag0len = length(rfrag0);
- rfrag1 = substr(str, len - rfrag0len + 1);
- str = substr(str, 1, len -= rfrag0len);
- if (rfrag0 != rfrag1) break;
- rfrag_matching_offset -= rfrag0len;
- }
- while (i && rfrag[i - 1] == "") i--; # empty fragment
- return i;
- }
- function rfrag_reduce(new_depth, _, c, i, brace, frags) {
- while (rfrag_depth > new_depth) {
- rfrag_depth--;
- c = rfrag_count[rfrag_depth];
- for (i = 0; i < c; i++)
- frags[i] = rfrag[rfrag_depth, i];
- frags[c] = rfrag[rfrag_depth];
- brace = simple_brace(frags, c + 1);
- if (rfrag_depth == 0)
- return brace;
- else
- rfrag[rfrag_depth - 1] = brace rfrag[rfrag_depth - 1];
- }
- }
- function rfrag_register(str, level, _, rfrag0, rfrag1, len) {
- if (level == rfrag_depth) {
- rfrag_depth = level + 1;
- rfrag[level] = "";
- rfrag_count[level] = 0;
- } else if (rfrag_depth != level + 1) {
- print "ERR(rfrag)";
- }
- rfrag0 = rfrag[level];
- rfrag1 = substr(str, 1, rfrag_matching_offset);
- len = rfrag_strlen_common(rfrag0, rfrag1);
- if (len == 0) {
- rfrag[level, rfrag_count[level]++] = rfrag0;
- rfrag[level] = rfrag1;
- } else {
- rfrag[level] = substr(rfrag0, length(rfrag0) - len + 1);
- rfrag[level + 1, 0] = substr(rfrag0, 1, length(rfrag0) - len);
- rfrag[level + 1] = substr(rfrag1, 1, length(rfrag1) - len);
- rfrag_count[level + 1] = 1;
- rfrag_depth++;
- }
- }
- function rfrag_dump(_, i, j, prefix) {
- print "depth = " rfrag_depth;
- for (i = 0; i < rfrag_depth; i++) {
- prefix = "";
- for (j = 0; j < i; j++) prefix = prefix " ";
- for (j = 0; j < rfrag_count[i]; j++)
- print prefix "rfrag[" i "," j "] = " rfrag[i,j];
- print prefix "rfrag[" i "] = " rfrag[i];
- }
- }
- function rfrag_brace(arr, len, _, i, level) {
- if (len == 0) return "";
- if (len == 1) return arr[0];
- rfrag_depth = 1;
- rfrag[0] = arr[0];
- rfrag_count[0] = 0;
- for (i = 1; i < len; i++) {
- level = rfrag_get_level(arr[i]);
- rfrag_reduce(level + 1);
- rfrag_register(arr[i], level);
- }
- return rfrag_reduce(0);
- }
- function lfrag_strlen_common(a, b, _, ret, abuf, bbuf, alen, blen, ia, ib) {
- ret = 0;
- alen = to_atoms(a, abuf);
- blen = to_atoms(b, bbuf);
- for (ia = ib = 0; ia < alen && ib < blen; ia++ + ib++) {
- if (abuf[ia] != bbuf[ib]) break;
- ret += length(abuf[ia]);
- }
- return ret;
- }
- function lfrag_get_level(str, _, i, frag0, frag0len, frag1) {
- lfrag_matching_offset = 0;
- for (i = 0; i < lfrag_depth - 1; i++) {
- frag0 = frag[i]
- frag0len = length(frag0);
- frag1 = substr(str, lfrag_matching_offset + 1, frag0len);
- if (frag0 != frag1) break;
- lfrag_matching_offset += frag0len;
- }
- while (i && frag[i - 1] == "") i--; # empty fragment
- return i;
- }
- function lfrag_reduce(new_depth, _, c, i, brace, frags) {
- while (lfrag_depth > new_depth) {
- lfrag_depth--;
- c = frag_count[lfrag_depth];
- for (i = 0; i < c; i++)
- frags[i] = frag[lfrag_depth, i];
- frags[c] = frag[lfrag_depth];
- brace = rfrag_brace(frags, c + 1);
- if (lfrag_depth == 0)
- return brace;
- else
- frag[lfrag_depth - 1] = frag[lfrag_depth - 1] brace;
- }
- }
- function lfrag_register(str, level, _, frag0, frag1, len) {
- if (lfrag_depth == level) {
- lfrag_depth = level + 1;
- frag[level] = "";
- frag_count[level] = 0;
- } else if (lfrag_depth != level + 1) {
- print "ERR";
- }
- frag0 = frag[level];
- frag1 = substr(str, lfrag_matching_offset + 1);
- len = lfrag_strlen_common(frag0, frag1);
- if (len == 0) {
- frag[level, frag_count[level]++] = frag0;
- frag[level] = frag1;
- } else {
- frag[level] = substr(frag0, 1, len);
- frag[level + 1, 0] = substr(frag0, len + 1);
- frag[level + 1] = substr(frag1, len + 1);
- frag_count[level + 1] = 1;
- lfrag_depth++;
- }
- }
- function lfrag_dump(_, i, j, prefix) {
- print "depth = " lfrag_depth;
- for (i = 0; i < lfrag_depth; i++) {
- prefix = "";
- for (j = 0; j < i; j++) prefix = prefix " ";
- for (j = 0; j < frag_count[i]; j++)
- print prefix "frag[" i "," j "] = " frag[i,j];
- print prefix "frag[" i "] = " frag[i];
- }
- }
- NR == 1 {
- lfrag_depth = 1;
- frag[0] = $0;
- frag_count[0] = 0;
- next
- }
- {
- level = lfrag_get_level($0);
- lfrag_reduce(level + 1);
- lfrag_register($0, level);
- }
- END {
- result = lfrag_reduce(0);
- result = remove_empty_quote(result);
- print result;
- }
- '
-}
-function ble/complete/insert-braces {
- if ((cand_count==1)); then
- ble/complete/insert-common; return "$?"
- fi
- local comps_len=${#COMPS} loop=0
- local -a tails=()
- local common=${cand_word[0]}
- ble/array#push tails "${common:comps_len}"
- local word clen=${#common}
- for word in "${cand_word[@]:1}"; do
- ((loop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- ((clen>${#word}&&(clen=${#word})))
- while [[ ${word::clen} != "${common::clen}" ]]; do
- ((clen--))
- done
- common=${common::clen}
- ble/array#push tails "${word:comps_len}"
- done
- local fixed=$COMPS
- if [[ $common != "$COMPS"* ]]; then
- tails=()
- local fixed= fixval=
- {
- [[ $comps_fixed ]] &&
- fixed=${COMPS::${comps_fixed%%:*}} fixval=${comps_fixed#*:}
- local ret simple_flags simple_ibrace
- ble/complete/candidates/determine-common-prefix/.apply-partial-comps # var[in,out] common
- if ble/syntax:bash/simple-word/reconstruct-incomplete-word "$common"; then
- ble/complete/source/eval-simple-word "$ret" single
- (($?==148)) && return 148
- fixed=$common fixval=$ret
- fi
- }
- local cand ret fixval_len=${#fixval}
- for cand in "${cand_cand[@]}"; do
- ((loop++%bleopt_complete_polling_cycle==0)) && ble/complete/check-cancel && return 148
- [[ $cand == "$fixval"* ]] || continue
- ble/complete/string#escape-for-completion-context "${cand:fixval_len}"
- case $comps in
- (*S*) cand=\'$ret\' ;;
- (*E*) cand=\$\'$ret\' ;;
- (*D*) cand=\"$ret\" ;;
- (*I*) cand=\$\"$ret\" ;;
- (*) cand=$ret ;;
- esac
- ble/array#push tails "$cand"
- done
- fi
- local tail; ble/util/assign tail 'ble/complete/insert-braces/.compose "${tails[@]}"'
- local beg=$COMP1 end=$COMP2 insert=$fixed$tail suffix=
- if [[ $comps_flags == *x* ]]; then
- ble/complete/action/complete.addtail ','
- else
- ble/complete/action/complete.addtail ' '
- fi
- ble/complete/insert "$beg" "$end" "$insert" "$suffix"
- blehook/invoke complete_insert
- _ble_complete_state=complete
- ble/complete/menu/clear
- return 0
-}
-_ble_complete_state=
-function ble/widget/complete {
- local opts=$1
- ble-edit/content/clear-arg
- local state=$_ble_complete_state
- _ble_complete_state=start
- local menu_show_opts=
- if [[ :$opts: != *:insert_*:* && :$opts: != *:show_menu:* ]]; then
- if [[ :$opts: == *:enter_menu:* ]]; then
- [[ $_ble_complete_menu_active && :$opts: != *:context=*:* ]] &&
- ble/complete/menu-complete/enter "$opts" && return 0
- elif [[ $bleopt_complete_menu_complete ]]; then
- if [[ $_ble_complete_menu_active && :$opts: != *:context=*:* ]]; then
- local footprint; ble/complete/menu/get-footprint
- [[ $footprint == "$_ble_complete_menu_footprint" ]] &&
- ble/complete/menu-complete/enter && return 0
- fi
- [[ $WIDGET == "$LASTWIDGET" && $state != complete ]] && opts=$opts:enter_menu
- fi
- fi
- local COMP1 COMP2 COMPS COMPV
- local comp_type comps_flags comps_fixed
- local cand_count cand_cand cand_word cand_pack
- ble/complete/candidates/clear
- local cand_limit_reached=
- if [[ $_ble_complete_menu_active && :$opts: != *:regenerate:* &&
- :$opts: != *:context=*:* && ${#_ble_complete_menu_icons[@]} -gt 0 ]]
- then
- if [[ $_ble_complete_menu_filter_enabled && $bleopt_complete_menu_filter ]] || {
- ble/complete/menu-filter; local ext=$?
- ((ext==148)) && return 148
- ((ext==0)); }; then
- ble/complete/menu/generate-candidates-from-menu; local ext=$?
- ((ext==148)) && return 148
- if ((ext==0&&cand_count)); then
- local bleopt_complete_menu_style=$_ble_complete_menu_style
- menu_show_opts=$menu_show_opts:menu-source # 既存の filter 前候補を保持する
- fi
- fi
- fi
- if ((cand_count==0)); then
- local bleopt_complete_menu_style=$bleopt_complete_menu_style # source 等に一次変更を認める。
- ble/complete/generate-candidates-from-opts "$opts"; local ext=$?
- if ((ext==148)); then
- return 148
- fi
- if [[ $cand_limit_reached ]]; then
- [[ :$opts: != *:no-bell:* ]] &&
- ble/widget/.bell 'complete: limit reached'
- if [[ $cand_limit_reached == cancel ]]; then
- ble/edit/info/default
- return 1
- fi
- fi
- if ((ext!=0||cand_count==0)); then
- [[ :$opts: != *:no-bell:* && ! $cand_limit_reached ]] &&
- ble/widget/.bell 'complete: no completions'
- ble/edit/info/default
- return 1
- fi
- fi
- if [[ :$opts: == *:insert_common:* ]]; then
- ble/complete/insert-common; return "$?"
- elif [[ :$opts: == *:insert_braces:* ]]; then
- ble/complete/insert-braces; return "$?"
- elif [[ :$opts: == *:insert_all:* ]]; then
- ble/complete/insert-all; return "$?"
- elif [[ :$opts: == *:enter_menu:* ]]; then
- local menu_common_part=$COMPV
- ble/complete/menu/show "$menu_show_opts" || return "$?"
- ble/complete/menu-complete/enter "$opts"; local ext=$?
- ((ext==148)) && return 148
- ((ext)) && [[ :$opts: != *:no-bell:* ]] &&
- ble/widget/.bell 'menu-complete: no completions'
- return 0
- elif [[ :$opts: == *:show_menu:* ]]; then
- local menu_common_part=$COMPV
- ble/complete/menu/show "$menu_show_opts"
- return "$?" # exit status of ble/complete/menu/show
- fi
- ble/complete/insert-common; return "$?"
-}
-function ble/widget/complete-insert {
- local original=$1 insert=$2 suffix=$3
- [[ ${_ble_edit_str::_ble_edit_ind} == *"$original" ]] || return 1
- local insert_beg=$((_ble_edit_ind-${#original}))
- local insert_end=$_ble_edit_ind
- ble/complete/insert "$insert_beg" "$insert_end" "$insert" "$suffix"
-}
-function ble/widget/menu-complete {
- local opts=$1
- ble/widget/complete enter_menu:$opts
-}
-function ble/complete/menu-filter/.filter-candidates {
- cand_pack=()
- local iloop=0 interval=$bleopt_complete_polling_cycle
- local filter_type pack "${_ble_complete_cand_varnames[@]/%/=}" # #D1570 WA checked
- for filter_type in head substr hsubseq subseq; do
- ble/path#remove-glob comp_type '[maA]'
- case $filter_type in
- (substr) comp_type=${comp_type}:m ;;
- (hsubseq) comp_type=${comp_type}:a ;;
- (subseq) comp_type=${comp_type}:A ;;
- esac
- local comp_filter_type
- local comp_filter_pattern
- ble/complete/candidates/filter#init "$filter_type" "$COMPV"
- for pack in "${_ble_complete_menu0_pack[@]}"; do
- ((iloop++%interval==0)) && ble/complete/check-cancel && return 148
- ble/complete/cand/unpack "$pack"
- ble/complete/candidates/filter#test "$CAND" &&
- ble/array#push cand_pack "$pack"
- done
- ((${#cand_pack[@]}!=0)) && return 0
- done
-}
-function ble/complete/menu-filter/.get-filter-target {
- if [[ $_ble_decode_keymap == emacs || $_ble_decode_keymap == vi_[ic]map ]]; then
- ret=$_ble_edit_str
- elif [[ $_ble_decode_keymap == auto_complete ]]; then
- ret=${_ble_edit_str::_ble_edit_ind}${_ble_edit_str:_ble_edit_mark}
- else
- return 1
- fi
-}
-function ble/complete/menu-filter {
- [[ $_ble_decode_keymap == menu_complete ]] && return 0
- local ret; ble/complete/menu-filter/.get-filter-target || return 1; local str=$ret
- local beg end; ble/complete/menu/get-active-range "$str" "$_ble_edit_ind" || return 1
- local input=${str:beg:end-beg}
- [[ $input == "${_ble_complete_menu_comp[2]}" ]] && return 0
- local simple_flags simple_ibrace
- if ! ble/syntax:bash/simple-word/reconstruct-incomplete-word "$input"; then
- ble/syntax:bash/simple-word/is-never-word "$input" && return 1
- return 0
- fi
- [[ $simple_ibrace ]] && ((${simple_ibrace%%:*}>10#0${_ble_complete_menu0_comp[6]%%:*})) && return 1 # 別のブレース展開要素に入った時
- ble/syntax:bash/simple-word/eval "$ret" single; (($?==148)) && return 148
- local COMPV=$ret
- local comp_type=${_ble_complete_menu0_comp[4]} cand_pack
- ble/complete/menu-filter/.filter-candidates; (($?==148)) && return 148
- local menu_common_part=$COMPV
- ble/complete/menu/show filter || return "$?"
- _ble_complete_menu_comp=("$beg" "$end" "$input" "$COMPV" "$comp_type")
- return 0
-}
-function ble/complete/menu-filter.idle {
- ble/util/idle.wait-user-input
- [[ $bleopt_complete_menu_filter ]] || return 1
- [[ $_ble_complete_menu_active ]] || return 1
- ble/complete/menu-filter; local ext=$?
- ((ext==148)) && return 148
- ((ext)) && ble/complete/menu/clear
- return 0
-}
-function ble/highlight/layer/buff#operate-gflags {
- local BUFF=$1 beg=$2 end=$3 mask=$4 gflags=$5
- ((beg<end)) || return 1
- if [[ $mask == auto ]]; then
- mask=0
- ((gflags&(_ble_color_gflags_FgIndexed|_ble_color_gflags_FgMask))) &&
- ((mask|=_ble_color_gflags_FgIndexed|_ble_color_gflags_FgMask))
- ((gflags&(_ble_color_gflags_BgIndexed|_ble_color_gflags_BgMask))) &&
- ((mask|=_ble_color_gflags_BgIndexed|_ble_color_gflags_BgMask))
- fi
- local i g ret
- for ((i=beg;i<end;i++)); do
- ble/highlight/layer/update/getg "$i"
- ((g=g&~mask|gflags))
- ble/color/g2sgr "$g"
- builtin eval -- "$BUFF[$i]=\$ret\${_ble_highlight_layer_plain_buff[$i]}"
- done
-}
-function ble/highlight/layer/buff#set-explicit-sgr {
- local BUFF=$1 index=$2
- builtin eval "((index<\${#$BUFF[@]}))" || return 1
- local g; ble/highlight/layer/update/getg "$index"
- local ret; ble/color/g2sgr "$g"
- builtin eval "$BUFF[index]=\$ret\${_ble_highlight_layer_plain_buff[index]}"
-}
-ble/color/defface menu_filter_fixed bold
-ble/color/defface menu_filter_input fg=16,bg=229
-_ble_highlight_layer_menu_filter_buff=()
-_ble_highlight_layer_menu_filter_beg=
-_ble_highlight_layer_menu_filter_end=
-function ble/highlight/layer:menu_filter/update {
- local text=$1 player=$2
- local obeg=$_ble_highlight_layer_menu_filter_beg
- local oend=$_ble_highlight_layer_menu_filter_end
- if [[ $obeg ]] && ((DMIN>=0)); then
- ((DMAX0<=obeg?(obeg+=DMAX-DMAX0):(DMIN<obeg&&(obeg=DMIN)),
- DMAX0<=oend?(oend+=DMAX-DMAX0):(DMIN<oend&&(oend=DMIN))))
- fi
- _ble_highlight_layer_menu_filter_beg=$obeg
- _ble_highlight_layer_menu_filter_end=$oend
- local beg= end= ret
- if [[ $bleopt_complete_menu_filter && $_ble_complete_menu_active && ${#_ble_complete_menu_icons[@]} -gt 0 ]]; then
- ble/complete/menu-filter/.get-filter-target && local str=$ret &&
- ble/complete/menu/get-active-range "$str" "$_ble_edit_ind" &&
- [[ ${str:beg:end-beg} != "${_ble_complete_menu0_comp[2]}" ]] || beg= end=
- fi
- [[ ! $obeg && ! $beg ]] && return 0
- ((PREV_UMIN<0)) && [[ $beg == "$obeg" && $end == "$oend" ]] &&
- PREV_BUFF=_ble_highlight_layer_menu_filter_buff && return 0
- local umin=$PREV_UMIN umax=$PREV_UMAX
- if [[ $beg ]]; then
- ble/color/face2g menu_filter_fixed; local gF=$ret
- ble/color/face2g menu_filter_input; local gI=$ret
- local mid=$_ble_complete_menu0_end
- ((mid<beg?(mid=beg):(end<mid&&(mid=end))))
- local buff_name=_ble_highlight_layer_menu_filter_buff
- builtin eval "$buff_name=(\"\${$PREV_BUFF[@]}\")"
- ble/highlight/layer/buff#operate-gflags "$buff_name" "$beg" "$mid" auto "$gF"
- ble/highlight/layer/buff#operate-gflags "$buff_name" "$mid" "$end" auto "$gI"
- ble/highlight/layer/buff#set-explicit-sgr "$buff_name" "$end"
- PREV_BUFF=$buff_name
- if [[ $obeg ]]; then :
- ble/highlight/layer:region/.update-dirty-range "$beg" "$obeg"
- ble/highlight/layer:region/.update-dirty-range "$end" "$oend"
- else
- ble/highlight/layer:region/.update-dirty-range "$beg" "$end"
- fi
- else
- if [[ $obeg ]]; then
- ble/highlight/layer:region/.update-dirty-range "$obeg" "$oend"
- fi
- fi
- _ble_highlight_layer_menu_filter_beg=$beg
- _ble_highlight_layer_menu_filter_end=$end
- ((PREV_UMIN=umin,PREV_UMAX=umax))
-}
-function ble/highlight/layer:menu_filter/getg {
- local index=$1
- local obeg=$_ble_highlight_layer_menu_filter_beg
- local oend=$_ble_highlight_layer_menu_filter_end
- local mid=$_ble_complete_menu0_end
- if [[ $obeg ]] && ((obeg<=index&&index<oend)); then
- local ret
- if ((index<mid)); then
- ble/color/face2g menu_filter_fixed; local g0=$ret
- else
- ble/color/face2g menu_filter_input; local g0=$ret
- fi
- ble/highlight/layer/update/getg "$index"
- ble/color/g.append "$g0"
- fi
-}
-_ble_complete_menu_filter_enabled=
-if ble/is-function ble/util/idle.push-background; then
- _ble_complete_menu_filter_enabled=1
- ble/util/idle.push -n 9999 ble/complete/menu-filter.idle
- ble/array#insert-before _ble_highlight_layer__list region menu_filter
-fi
-_ble_complete_menu_original=
-function ble/complete/menu-complete/select {
- ble/complete/menu#select "$@"
-}
-function ble/complete/menu-complete/enter {
- ((${#_ble_complete_menu_icons[@]}>=1)) || return 1
- local beg end; ble/complete/menu/get-active-range || return 1
- local opts=$1
- _ble_edit_mark=$beg
- _ble_edit_ind=$end
- local comps_fixed=${_ble_complete_menu0_comp[6]}
- if [[ $comps_fixed ]]; then
- local comps_fixed_length=${comps_fixed%%:*}
- ((_ble_edit_mark+=comps_fixed_length))
- fi
- _ble_complete_menu_original=${_ble_edit_str:beg:end-beg}
- ble/complete/menu/redraw
- if [[ :$opts: == *:backward:* ]]; then
- ble/complete/menu#select $((${#_ble_complete_menu_items[@]}-1))
- else
- ble/complete/menu#select 0
- fi
- _ble_edit_mark_active=insert
- ble/decode/keymap/push menu_complete
- return 0
-}
-function ble/widget/menu_complete/exit {
- local opts=$1
- ble/decode/keymap/pop
- if ((_ble_complete_menu_selected>=0)); then
- local new=${_ble_edit_str:_ble_complete_menu0_beg:_ble_edit_ind-_ble_complete_menu0_beg}
- local old=$_ble_complete_menu_original
- local comp_text=${_ble_edit_str::_ble_complete_menu0_beg}$old${_ble_edit_str:_ble_edit_ind}
- local insert_beg=$_ble_complete_menu0_beg
- local insert_end=$((_ble_complete_menu0_beg+${#old}))
- local insert=$new
- local insert_flags=
- local suffix=
- if [[ :$opts: == *:complete:* ]]; then
- local icon=${_ble_complete_menu_icons[_ble_complete_menu_selected-_ble_complete_menu_offset]}
- local icon_data=${icon#*:} icon_fields
- ble/string#split icon_fields , "${icon%%:*}"
- local pack=${icon_data::icon_fields[4]}
- local ACTION=${pack%%:*}
- if ble/is-function ble/complete/action:"$ACTION"/complete; then
- local COMP1=${_ble_complete_menu0_comp[0]}
- local COMP2=${_ble_complete_menu0_comp[1]}
- local COMPS=${_ble_complete_menu0_comp[2]}
- local COMPV=${_ble_complete_menu0_comp[3]}
- local comp_type=${_ble_complete_menu0_comp[4]}
- local comps_flags=${_ble_complete_menu0_comp[5]}
- local comps_fixed=${_ble_complete_menu0_comp[6]}
- local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
- ble/complete/cand/unpack "$pack"
- ble/complete/action:"$ACTION"/complete
- fi
- ble/complete/insert "$_ble_complete_menu0_beg" "$_ble_edit_ind" "$insert" "$suffix"
- fi
- blehook/invoke complete_insert
- fi
- ble/complete/menu/clear
- _ble_edit_mark_active=
- _ble_complete_menu_original=
-}
-function ble/widget/menu_complete/cancel {
- ble/decode/keymap/pop
- ble/complete/menu#select -1
- _ble_edit_mark_active=
- _ble_complete_menu_original=
-}
-function ble/widget/menu_complete/accept {
- ble/widget/menu_complete/exit complete
-}
-function ble/widget/menu_complete/exit-default {
- ble/widget/menu_complete/exit
- ble/decode/widget/skip-lastwidget
- ble/decode/widget/redispatch-by-keys "${KEYS[@]}"
-}
-function ble-decode/keymap:menu_complete/define {
- ble-bind -f __default__ 'menu_complete/exit-default'
- ble-bind -f __line_limit__ nop
- ble-bind -f C-m 'menu_complete/accept'
- ble-bind -f RET 'menu_complete/accept'
- ble-bind -f C-g 'menu_complete/cancel'
- ble-bind -f 'C-x C-g' 'menu_complete/cancel'
- ble-bind -f 'C-M-g' 'menu_complete/cancel'
- ble-bind -f C-f 'menu/forward-column'
- ble-bind -f right 'menu/forward-column'
- ble-bind -f C-i 'menu/forward cyclic'
- ble-bind -f TAB 'menu/forward cyclic'
- ble-bind -f C-b 'menu/backward-column'
- ble-bind -f left 'menu/backward-column'
- ble-bind -f C-S-i 'menu/backward cyclic'
- ble-bind -f S-TAB 'menu/backward cyclic'
- ble-bind -f C-n 'menu/forward-line'
- ble-bind -f down 'menu/forward-line'
- ble-bind -f C-p 'menu/backward-line'
- ble-bind -f up 'menu/backward-line'
- ble-bind -f prior 'menu/backward-page'
- ble-bind -f next 'menu/forward-page'
- ble-bind -f home 'menu/beginning-of-page'
- ble-bind -f end 'menu/end-of-page'
-}
-function ble/complete/auto-complete/initialize {
- local ret
- ble-decode-kbd/generate-keycode auto_complete_enter
- _ble_complete_KCODE_ENTER=$ret
-}
-ble/complete/auto-complete/initialize
-function ble/highlight/layer:region/mark:auto_complete/get-face {
- face=auto_complete
-}
-_ble_complete_ac_type=
-_ble_complete_ac_comp1=
-_ble_complete_ac_cand=
-_ble_complete_ac_word=
-_ble_complete_ac_insert=
-_ble_complete_ac_suffix=
-function ble/complete/auto-complete/.search-history-light {
- [[ $_ble_history_prefix ]] && return 1
- local text=$1
- [[ ! $text ]] && return 1
- local wordbreaks="<>();&|:$_ble_term_IFS"
- local word= expand
- if [[ $text != [-0-9#?!]* ]]; then
- word=${text%%[$wordbreaks]*}
- command='!'$word ble/util/assign expand 'ble/edit/hist_expanded/.core' &>/dev/null || return 1
- if [[ $expand == "$text"* ]]; then
- ret=$expand
- return 0
- fi
- fi
- if [[ $word != "$text" ]]; then
- local fragments; ble/string#split fragments '?' "$text"
- local frag longest_fragments len=0; longest_fragments=('')
- for frag in "${fragments[@]}"; do
- local len1=${#frag}
- ((len1>len&&(len=len1))) && longest_fragments=()
- ((len1==len)) && ble/array#push longest_fragments "$frag"
- done
- for frag in "${longest_fragments[@]}"; do
- command='!?'$frag ble/util/assign expand 'ble/edit/hist_expanded/.core' &>/dev/null || return 1
- [[ $expand == "$text"* ]] || continue
- ret=$expand
- return 0
- done
- fi
- return 1
-}
-_ble_complete_ac_history_needle=
-_ble_complete_ac_history_index=
-_ble_complete_ac_history_start=
-function ble/complete/auto-complete/.search-history-heavy {
- local text=$1
- local count; ble/history/get-count -v count
- local start=$((count-1))
- local index=$((count-1))
- local needle=$text
- ((start==_ble_complete_ac_history_start)) &&
- [[ $needle == "$_ble_complete_ac_history_needle"* ]] &&
- index=$_ble_complete_ac_history_index
- local isearch_time=0 isearch_ntask=1
- local isearch_opts=head
- [[ :$comp_type: == *:sync:* ]] || isearch_opts=$isearch_opts:stop_check
- ble/history/isearch-backward-blockwise "$isearch_opts"; local ext=$?
- _ble_complete_ac_history_start=$start
- _ble_complete_ac_history_index=$index
- _ble_complete_ac_history_needle=$needle
- ((ext)) && return "$ext"
- ble/history/get-edited-entry -v ret "$index"
- return 0
-}
-function ble/complete/auto-complete/.enter-auto-complete-mode {
- _ble_complete_ac_type=$type
- _ble_complete_ac_comp1=$COMP1
- _ble_complete_ac_cand=$cand
- _ble_complete_ac_word=$word
- _ble_complete_ac_insert=$insert
- _ble_complete_ac_suffix=$suffix
- _ble_edit_mark_active=auto_complete
- ble/decode/keymap/push auto_complete
- ble-decode-key "$_ble_complete_KCODE_ENTER" # dummy key input to record keyboard macros
-}
-function ble/complete/auto-complete/.insert {
- local insert=$1
- ble-edit/content/replace-limited "$_ble_edit_ind" "$_ble_edit_ind" "$insert" nobell
- ((_ble_edit_mark=_ble_edit_ind+${#insert}))
-}
-function ble/complete/auto-complete/.check-history {
- local opts=$1
- local searcher=.search-history-heavy
- [[ :$opts: == *:light:* ]] && searcher=.search-history-light
- local ret
- ((_ble_edit_ind==${#_ble_edit_str})) || return 1
- ble/complete/auto-complete/"$searcher" "$_ble_edit_str" || return "$?" # 0, 1 or 148
- local word=$ret cand=
- local COMP1=0 COMPS=$_ble_edit_str
- [[ $word == "$COMPS" ]] && return 1
- local insert=$word suffix=
- local type=h
- ble/complete/auto-complete/.insert "${insert:${#COMPS}}"
- ble/complete/auto-complete/.enter-auto-complete-mode
- return 0
-}
-function ble/complete/auto-complete/.check-context {
- local sources
- ble/complete/context:syntax/generate-sources "$comp_text" "$comp_index" &&
- ble/complete/context/filter-prefix-sources || return 1
- local bleopt_complete_contract_function_names=
- local bleopt_complete_menu_style=$bleopt_complete_menu_style # source local settings
- ((bleopt_complete_polling_cycle>25)) &&
- local bleopt_complete_polling_cycle=25
- local COMP1 COMP2 COMPS COMPV
- local comps_flags comps_fixed
- local cand_count cand_cand cand_word cand_pack
- local cand_limit_reached=
- ble/complete/candidates/generate; local ext=$?
- [[ $COMPV ]] || return 1
- ((ext)) && return "$ext"
- ((cand_count)) || return 1
- local word=${cand_word[0]} cand=${cand_cand[0]}
- [[ $word == "$COMPS" ]] && return 1
- local insert=$word suffix=
- local ACTION=${cand_pack[0]%%:*}
- if ble/is-function ble/complete/action:"$ACTION"/complete; then
- local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
- ble/complete/cand/unpack "${cand_pack[0]}"
- ble/complete/action:"$ACTION"/complete
- fi
- local type=
- if [[ $insert == "$COMPS"* ]]; then
- [[ ${comp_text:COMP1} == "$insert"* ]] && return 1
- type=c
- ble/complete/auto-complete/.insert "${insert:${#COMPS}}"
- else
- case :$comp_type: in
- (*:a:*) type=a ;;
- (*:m:*) type=m ;;
- (*:A:*) type=A ;;
- (*) type=r ;;
- esac
- ble/complete/auto-complete/.insert " [$insert] "
- fi
- ble/complete/auto-complete/.enter-auto-complete-mode
- return 0
-}
-function ble/complete/auto-complete.impl {
- local opts=$1
- local comp_type=auto
- [[ :$opts: == *:sync:* ]] && comp_type=${comp_type}:sync
- local comp_text=$_ble_edit_str comp_index=$_ble_edit_ind
- [[ $comp_text ]] || return 0
- if local beg end; ble/complete/menu/get-active-range "$_ble_edit_str" "$_ble_edit_ind"; then
- ((_ble_edit_ind<end)) && return 0
- fi
- if [[ $bleopt_complete_auto_history ]]; then
- ble/complete/auto-complete/.check-history light; local ext=$?
- ((ext==0||ext==148)) && return "$ext"
- [[ $_ble_history_prefix || $_ble_history_load_done ]] &&
- ble/complete/auto-complete/.check-history; local ext=$?
- ((ext==0||ext==148)) && return "$ext"
- fi
- ble/complete/auto-complete/.check-context
-}
-function ble/complete/auto-complete.idle {
- ble/util/idle.wait-user-input
- [[ $bleopt_complete_auto_complete ]] || return 1
- [[ $_ble_decode_keymap == emacs || $_ble_decode_keymap == vi_[ic]map ]] || return 0
- case $_ble_decode_widget_last in
- (ble/widget/self-insert) ;;
- (ble/widget/complete) ;;
- (ble/widget/vi_imap/complete) ;;
- (*) return 0 ;;
- esac
- [[ $_ble_edit_str ]] || return 0
- ble/util/idle.sleep-until $((_idle_clock_start+bleopt_complete_auto_delay)) checked && return 0
- ble/complete/auto-complete.impl
-}
-function ble/complete/auto-menu.idle {
- ble/util/idle.wait-user-input
- [[ $_ble_complete_menu_active ]] && return 0
- ((bleopt_complete_auto_menu>0)) || return 1
- case $_ble_decode_widget_last in
- (ble/widget/self-insert) ;;
- (ble/widget/complete) ;;
- (ble/widget/vi_imap/complete) ;;
- (ble/widget/auto_complete/self-insert) ;;
- (*) return 0 ;;
- esac
- [[ $_ble_edit_str ]] || return 0
- local until=$((_idle_clock_start+bleopt_complete_auto_menu))
- ble/util/idle.sleep-until "$until" checked && return 0
- ble/widget/complete auto_menu:show_menu:no-empty:no-bell
-}
-ble/function#try ble/util/idle.push-background ble/complete/auto-complete.idle
-ble/function#try ble/util/idle.push-background ble/complete/auto-menu.idle
-function ble/widget/auto-complete-enter {
- ble/complete/auto-complete.impl sync
-}
-function ble/widget/auto_complete/cancel {
- ble/decode/keymap/pop
- ble-edit/content/replace "$_ble_edit_ind" "$_ble_edit_mark" ''
- _ble_edit_mark=$_ble_edit_ind
- _ble_edit_mark_active=
- _ble_complete_ac_insert=
- _ble_complete_ac_suffix=
-}
-function ble/widget/auto_complete/insert {
- ble/decode/keymap/pop
- ble-edit/content/replace "$_ble_edit_ind" "$_ble_edit_mark" ''
- _ble_edit_mark=$_ble_edit_ind
- local comp_text=$_ble_edit_str
- local insert_beg=$_ble_complete_ac_comp1
- local insert_end=$_ble_edit_ind
- local insert=$_ble_complete_ac_insert
- local suffix=$_ble_complete_ac_suffix
- ble/complete/insert "$insert_beg" "$insert_end" "$insert" "$suffix"
- blehook/invoke complete_insert
- _ble_edit_mark_active=
- _ble_complete_ac_insert=
- _ble_complete_ac_suffix=
- ble/complete/menu/clear
- ble-edit/content/clear-arg
- return 0
-}
-function ble/widget/auto_complete/cancel-default {
- ble/widget/auto_complete/cancel
- ble/decode/widget/skip-lastwidget
- ble/decode/widget/redispatch-by-keys "${KEYS[@]}"
-}
-function ble/widget/auto_complete/self-insert {
- local code; ble/widget/self-insert/.get-code
- ((code==0)) && return 0
- local ret
- ble/util/c2s "$code"; local ins=$ret
- local comps_cur=${_ble_edit_str:_ble_complete_ac_comp1:_ble_edit_ind-_ble_complete_ac_comp1}
- local comps_new=$comps_cur$ins
- local processed=
- if [[ $_ble_complete_ac_type == [ch] ]]; then
- if [[ $_ble_complete_ac_word == "$comps_new"* ]]; then
- ((_ble_edit_ind+=${#ins}))
- [[ ! $_ble_complete_ac_word ]] && ble/widget/auto_complete/cancel
- processed=1
- fi
- elif [[ $_ble_complete_ac_type == [rmaA] && $ins != [{,}] ]]; then
- if local ret simple_flags simple_ibrace; ble/syntax:bash/simple-word/reconstruct-incomplete-word "$comps_new"; then
- if ble/complete/source/eval-simple-word "$ret" single && local compv_new=$ret; then
- local filter_type=head
- case $_ble_complete_ac_type in
- (*m*) filter_type=substr ;;
- (*a*) filter_type=hsubseq ;;
- (*A*) filter_type=subseq ;;
- esac
- local comps_fixed=
- local comp_filter_type
- local comp_filter_pattern
- ble/complete/candidates/filter#init "$filter_type" "$compv_new"
- if ble/complete/candidates/filter#test "$_ble_complete_ac_cand"; then
- local insert; ble-edit/content/replace-limited "$_ble_edit_ind" "$_ble_edit_ind" "$ins"
- ((_ble_edit_ind+=${#insert},_ble_edit_mark+=${#insert}))
- [[ $_ble_complete_ac_cand == "$compv_new" ]] &&
- ble/widget/auto_complete/cancel
- processed=1
- fi
- fi
- fi
- fi
- if [[ $processed ]]; then
- local comp_text= insert_beg=0 insert_end=0 insert=$ins suffix=
- blehook/invoke complete_insert
- return 0
- else
- ble/widget/auto_complete/cancel
- ble/decode/widget/skip-lastwidget
- ble/decode/widget/redispatch-by-keys "${KEYS[@]}"
- fi
-}
-function ble/widget/auto_complete/insert-on-end {
- if ((_ble_edit_mark==${#_ble_edit_str})); then
- ble/widget/auto_complete/insert
- else
- ble/widget/auto_complete/cancel-default
- fi
-}
-function ble/widget/auto_complete/insert-word {
- local breaks=${bleopt_complete_auto_wordbreaks:-$_ble_term_IFS}
- local rex='^['$breaks']*([^'$breaks']+['$breaks']*)?'
- if [[ $_ble_complete_ac_type == [ch] ]]; then
- local ins=${_ble_edit_str:_ble_edit_ind:_ble_edit_mark-_ble_edit_ind}
- [[ $ins =~ $rex ]]
- if [[ $BASH_REMATCH == "$ins" ]]; then
- ble/widget/auto_complete/insert
- return 0
- else
- local ins=$BASH_REMATCH
- ((_ble_edit_ind+=${#ins}))
- local comp_text=$_ble_edit_str
- local insert_beg=$_ble_complete_ac_comp1
- local insert_end=$_ble_edit_ind
- local insert=${_ble_edit_str:insert_beg:insert_end-insert_beg}$ins
- local suffix=
- blehook/invoke complete_insert
- return 0
- fi
- elif [[ $_ble_complete_ac_type == [rmaA] ]]; then
- local ins=$_ble_complete_ac_insert
- [[ $ins =~ $rex ]]
- if [[ $BASH_REMATCH == "$ins" ]]; then
- ble/widget/auto_complete/insert
- return 0
- else
- local ins=$BASH_REMATCH
- _ble_complete_ac_type=c
- ble-edit/content/replace "$_ble_complete_ac_comp1" "$_ble_edit_mark" "$_ble_complete_ac_insert"
- ((_ble_edit_ind=_ble_complete_ac_comp1+${#ins},
- _ble_edit_mark=_ble_complete_ac_comp1+${#_ble_complete_ac_insert}))
- local comp_text=$_ble_edit_str
- local insert_beg=$_ble_complete_ac_comp1
- local insert_end=$_ble_edit_ind
- local insert=$ins
- local suffix=
- blehook/invoke complete_insert
- return 0
- fi
- fi
- return 1
-}
-function ble/widget/auto_complete/accept-line {
- ble/widget/auto_complete/insert
- ble-decode-key 13
-}
-function ble/widget/auto_complete/notify-enter {
- ble/decode/widget/skip-lastwidget
-}
-function ble-decode/keymap:auto_complete/define {
- ble-bind -f __defchar__ auto_complete/self-insert
- ble-bind -f __default__ auto_complete/cancel-default
- ble-bind -f __line_limit__ nop
- ble-bind -f 'C-g' auto_complete/cancel
- ble-bind -f 'C-x C-g' auto_complete/cancel
- ble-bind -f 'C-M-g' auto_complete/cancel
- ble-bind -f S-RET auto_complete/insert
- ble-bind -f S-C-m auto_complete/insert
- ble-bind -f C-f auto_complete/insert-on-end
- ble-bind -f right auto_complete/insert-on-end
- ble-bind -f C-e auto_complete/insert-on-end
- ble-bind -f end auto_complete/insert-on-end
- ble-bind -f M-f auto_complete/insert-word
- ble-bind -f M-right auto_complete/insert-word
- ble-bind -f C-j auto_complete/accept-line
- ble-bind -f C-RET auto_complete/accept-line
- ble-bind -f auto_complete_enter auto_complete/notify-enter
-}
-function ble/complete/sabbrev/.initialize-print {
- sgr0= sgr1= sgr2= sgr3= sgro=
- if [[ $flags == *c* || $flags != *n* && -t 1 ]]; then
- local ret
- ble/color/face2sgr command_function; sgr1=$ret
- ble/color/face2sgr syntax_varname; sgr2=$ret
- ble/color/face2sgr syntax_quoted; sgr3=$ret
- ble/color/face2sgr argument_option; sgro=$ret
- sgr0=$_ble_term_sgr0
- fi
-}
-function ble/complete/sabbrev/.print-definition {
- local key=$1 type=${2%%:*} value=${2#*:}
- local option=
- [[ $type == m ]] && option=$sgro'-m'$sgr0' '
- local ret
- ble/string#quote-word "$key" quote-empty:sgrq="$sgr3":sgr0="$sgr2"
- key=$sgr2$ret$sgr0
- ble/string#quote-word "$value" sgrq="$sgr3":sgr0="$sgr0"
- value=$ret
- ble/util/print "${sgr1}ble-sabbrev$sgr0 $option$key=$value"
-}
-function ble/complete/sabbrev/register {
- local key=$1 value=$2
- ble/gdict#set _ble_complete_sabbrev "$key" "$value"
-}
-function ble/complete/sabbrev/list {
- local keys ret; keys=("$@")
- if ((${#keys[@]}==0)); then
- ble/gdict#keys _ble_complete_sabbrev
- keys=("${ret[@]}")
- ((${#keys[@]})) || return 0
- fi
- local sgr0 sgr1 sgr2 sgr3 sgro
- ble/complete/sabbrev/.initialize-print
- local key ext=0
- for key in "${keys[@]}"; do
- if ble/gdict#get _ble_complete_sabbrev "$key"; then
- ble/complete/sabbrev/.print-definition "$key" "$ret"
- else
- ble/util/print "ble-sabbrev: $key: not found." >&2
- ext=1
- fi
- done
- return "$ext"
-}
-function ble/complete/sabbrev/reset {
- if (($#)); then
- local key
- for key; do
- ble/gdict#unset _ble_complete_sabbrev "$key"
- done
- else
- ble/gdict#clear _ble_complete_sabbrev
- fi
- return 0
-}
-function ble/complete/sabbrev/get {
- local key=$1
- ble/gdict#get _ble_complete_sabbrev "$key"
-}
-function ble/complete/sabbrev/get-keys {
- local ret
- ble/gdict#keys _ble_complete_sabbrev
- keys=("${ret[@]}")
-}
-function ble/complete/sabbrev/read-arguments {
- while (($#)); do
- local arg=$1; shift
- if [[ $arg == ?*=* ]]; then
- ble/array#push specs "s:$arg"
- else
- case $arg in
- (--help)
- flags=H$flags ;;
- (--reset)
- flags=r$flags
- (--color|--color=always)
- flags=c${flags//[cn]} ;;
- (--color=never)
- flags=n${flags//[cn]} ;;
- (--color=auto)
- flags=${flags//[cn]} ;;
- (-*)
- local i n=${#arg} c
- for ((i=1;i<n;i++)); do
- c=${arg:i:1}
- case $c in
- (m)
- if ((!$#)); then
- ble/util/print "ble-sabbrev: option argument for '-$c' is missing" >&2
- flags=E$flags
- elif [[ $1 != ?*=* ]]; then
- ble/util/print "ble-sabbrev: invalid option argument '-$c $1' (expected form: '-$c key=value')" >&2
- flags=E$flags
- else
- ble/array#push specs "$c:$1"; shift
- fi ;;
- (r)
- flags=r$flags ;;
- (*)
- ble/util/print "ble-sabbrev: unknown option '-$c'." >&2
- flags=E$flags ;;
- esac
- done ;;
- (*)
- ble/array#push print "$arg" ;;
- esac
- fi
- done
-}
-function ble-sabbrev {
- local -a specs=() print=()
- local flags=
- ble/complete/sabbrev/read-arguments "$@"
- if [[ $flags == *H* || $flags == *E* ]]; then
- [[ $flags == *E* ]] && ble/util/print
- ble/util/print-lines \
- 'usage: ble-sabbrev [KEY=VALUE|-m KEY=FUNCTION]...' \
- 'usage: ble-sabbrev [-r|--reset] [KEY...]' \
- 'usage: ble-sabbrev --help' \
- ' Register sabbrev expansion.'
- [[ ! $flags == *E* ]]; return "$?"
- fi
- local ext=0
- if ((${#specs[@]}==0||${#print[@]})); then
- if [[ $flags == *r* ]]; then
- ble/complete/sabbrev/reset "${print[@]}"
- else
- ble/complete/sabbrev/list "${print[@]}"
- fi || ext=$?
- fi
- local spec key type value
- for spec in "${specs[@]}"; do
- type=${spec::1} spec=${spec:2}
- key=${spec%%=*} value=${spec#*=}
- ble/complete/sabbrev/register "$key" "$type:$value"
- done
- return "$ext"
-}
-function ble/complete/sabbrev/expand {
- local sources comp_index=$_ble_edit_ind comp_text=$_ble_edit_str
- ble/complete/context:syntax/generate-sources
- local src asrc pos=$comp_index
- for src in "${sources[@]}"; do
- ble/string#split-words asrc "$src"
- case ${asrc[0]} in
- (file|command|argument|variable:w|wordlist:*|sabbrev)
- ((asrc[1]<pos)) && pos=${asrc[1]} ;;
- esac
- done
- ((pos<comp_index)) || return 1
- local key=${_ble_edit_str:pos:comp_index-pos}
- local ret; ble/complete/sabbrev/get "$key" || return 1
- local type=${ret%%:*} value=${ret#*:}
- case $type in
- (s)
- ble/widget/.replace-range "$pos" "$comp_index" "$value"
- ((_ble_edit_ind=pos+${#value})) ;;
- (m)
- local comp_type= comps_flags= comps_fixed=
- local COMP1=$pos COMP2=$pos COMPS=$key COMPV=
- ble/complete/candidates/comp_type#read-rl-variables
- local flag_force_fignore=
- local flag_source_filter=1
- local cand_count cand_cand cand_word cand_pack
- ble/complete/candidates/clear
- local COMP_PREFIX=
- local bleopt_sabbrev_menu_style=$bleopt_complete_menu_style
- local bleopt_sabbrev_menu_opts=
- local -a COMPREPLY=()
- builtin eval -- "$value"
- local cand action=word "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- for cand in "${COMPREPLY[@]}"; do
- ble/complete/cand/yield "$action" "$cand" ""
- done
- if ((cand_count==0)); then
- return 1
- elif ((cand_count==1)); then
- local value=${cand_word[0]}
- ble/widget/.replace-range "$pos" "$comp_index" "$value"
- ((_ble_edit_ind=pos+${#value}))
- return 0
- fi
- ble/widget/.replace-range "$pos" "$comp_index" ''
- local bleopt_complete_menu_style=$bleopt_sabbrev_menu_style
- local menu_common_part=
- ble/complete/menu/show || return "$?"
- [[ :$bleopt_sabbrev_menu_opts: == *:enter_menu:* ]] &&
- ble/complete/menu-complete/enter
- return 147 ;;
- (*) return 1 ;;
- esac
- return 0
-}
-function ble/widget/sabbrev-expand {
- if ! ble/complete/sabbrev/expand; then
- ble/widget/.bell
- return 1
- fi
-}
-function ble/complete/action:sabbrev/initialize { CAND=$value; }
-function ble/complete/action:sabbrev/complete { :; }
-function ble/complete/action:sabbrev/init-menu-item {
- local ret; ble/color/face2g command_alias; g=$ret
- show=$INSERT
-}
-function ble/complete/action:sabbrev/get-desc {
- local ret; ble/complete/sabbrev/get "$INSERT"
- desc="$desc_sgrt(sabbrev)$desc_sgr0 $ret"
-}
-function ble/complete/source:sabbrev {
- local keys; ble/complete/sabbrev/get-keys
- local filter_type=$comp_filter_type
- [[ $filter_type == none ]] && filter_type=head
- local comps_fixed=
- local comp_filter_type
- local comp_filter_pattern
- ble/complete/candidates/filter#init "$filter_type" "$COMPS"
- local cand action=sabbrev "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- for cand in "${keys[@]}"; do
- ble/complete/candidates/filter#test "$cand" || continue
- local ret simple_flags simple_ibrace
- ble/syntax:bash/simple-word/reconstruct-incomplete-word "$cand" &&
- ble/complete/source/eval-simple-word "$ret" single || continue
- local value=$ret # referenced in "ble/complete/action:sabbrev/initialize"
- local flag_source_filter=1
- ble/complete/cand/yield "$action" "$cand"
- done
-}
-_ble_complete_dabbrev_original=
-_ble_complete_dabbrev_regex1=
-_ble_complete_dabbrev_regex2=
-_ble_complete_dabbrev_index=
-_ble_complete_dabbrev_pos=
-_ble_complete_dabbrev_stack=()
-function ble/complete/dabbrev/.show-status.fib {
- local index='!'$((_ble_complete_dabbrev_index+1))
- local nmatch=${#_ble_complete_dabbrev_stack[@]}
- local needle=$_ble_complete_dabbrev_original
- local text="(dabbrev#$nmatch: << $index) \`$needle'"
- local pos=$1
- if [[ $pos ]]; then
- local count; ble/history/get-count
- local percentage=$((count?pos*1000/count:1000))
- text="$text searching... @$pos ($((percentage/10)).$((percentage%10))%)"
- fi
- ((fib_ntask)) && text="$text *$fib_ntask"
- ble/edit/info/show text "$text"
-}
-function ble/complete/dabbrev/show-status {
- local fib_ntask=${#_ble_util_fiberchain[@]}
- ble/complete/dabbrev/.show-status.fib
-}
-function ble/complete/dabbrev/erase-status {
- ble/edit/info/default
-}
-function ble/complete/dabbrev/initialize-variables {
- local wordbreaks; ble/complete/get-wordbreaks
- _ble_complete_dabbrev_wordbreaks=$wordbreaks
- local left=${_ble_edit_str::_ble_edit_ind}
- local original=${left##*[$wordbreaks]}
- local p1=$((_ble_edit_ind-${#original})) p2=$_ble_edit_ind
- _ble_edit_mark=$p1
- _ble_edit_ind=$p2
- _ble_complete_dabbrev_original=$original
- local ret; ble/string#escape-for-extended-regex "$original"
- local needle='(^|['$wordbreaks'])'$ret
- _ble_complete_dabbrev_regex1=$needle
- _ble_complete_dabbrev_regex2='('$needle'[^'$wordbreaks']*).*'
- local index; ble/history/get-index
- _ble_complete_dabbrev_index=$index
- _ble_complete_dabbrev_pos=${#_ble_edit_str}
- _ble_complete_dabbrev_stack=()
-}
-function ble/complete/dabbrev/reset {
- local original=$_ble_complete_dabbrev_original
- ble-edit/content/replace "$_ble_edit_mark" "$_ble_edit_ind" "$original"
- ((_ble_edit_ind=_ble_edit_mark+${#original}))
- _ble_edit_mark_active=
-}
-function ble/complete/dabbrev/search-in-history-entry {
- local line=$1 index=$2
- local index_editing; ble/history/get-index -v index_editing
- if ((index!=index_editing)); then
- local pos=$dabbrev_pos
- while [[ ${line:pos} && ${line:pos} =~ $_ble_complete_dabbrev_regex2 ]]; do
- local rematch1=${BASH_REMATCH[1]} rematch2=${BASH_REMATCH[2]}
- local match=${rematch1:${#rematch2}}
- if [[ $match && $match != "$dabbrev_current_match" ]]; then
- dabbrev_match=$match
- dabbrev_match_pos=$((${#line}-${#BASH_REMATCH}+${#match}))
- return 0
- else
- ((pos++))
- fi
- done
- fi
- return 1
-}
-function ble/complete/dabbrev/.search.fib {
- if [[ ! $fib_suspend ]]; then
- local start=$_ble_complete_dabbrev_index
- local index=$_ble_complete_dabbrev_index
- local pos=$_ble_complete_dabbrev_pos
- ((--start>=0)) || ble/history/get-count -v start
- else
- local start index pos; builtin eval -- "$fib_suspend"
- fib_suspend=
- fi
- local dabbrev_match=
- local dabbrev_pos=$pos
- local dabbrev_current_match=${_ble_edit_str:_ble_edit_mark:_ble_edit_ind-_ble_edit_mark}
- local line; ble/history/get-edited-entry -v line "$index"
- if ! ble/complete/dabbrev/search-in-history-entry "$line" "$index"; then
- ((index--,dabbrev_pos=0))
- local isearch_time=0
- local isearch_opts=stop_check:cyclic
- isearch_opts=$isearch_opts:condition
- local dabbrev_original=$_ble_complete_dabbrev_original
- local dabbrev_regex1=$_ble_complete_dabbrev_regex1
- local needle='[[ $LINE =~ $dabbrev_regex1 ]] && ble/complete/dabbrev/search-in-history-entry "$LINE" "$INDEX"'
- [[ $dabbrev_original ]] && needle='[[ $LINE == *"$dabbrev_original"* ]] && '$needle
- isearch_opts=$isearch_opts:progress
- local isearch_progress_callback=ble/complete/dabbrev/.show-status.fib
- ble/history/isearch-backward-blockwise "$isearch_opts"; local ext=$?
- ((ext==148)) && fib_suspend="start=$start index=$index pos=$pos"
- if ((ext)); then
- if ((${#_ble_complete_dabbrev_stack[@]})); then
- ble/widget/.bell # 周回したので鳴らす
- return 0
- else
- return "$ext"
- fi
- fi
- fi
- local rec=$_ble_complete_dabbrev_index,$_ble_complete_dabbrev_pos,$_ble_edit_ind,$_ble_edit_mark
- ble/array#push _ble_complete_dabbrev_stack "$rec:$_ble_edit_str"
- local insert; ble-edit/content/replace-limited "$_ble_edit_mark" "$_ble_edit_ind" "$dabbrev_match"
- ((_ble_edit_ind=_ble_edit_mark+${#insert}))
- ((index>_ble_complete_dabbrev_index)) &&
- ble/widget/.bell # 周回
- _ble_complete_dabbrev_index=$index
- _ble_complete_dabbrev_pos=$dabbrev_match_pos
- ble/textarea#redraw
-}
-function ble/complete/dabbrev/next.fib {
- ble/complete/dabbrev/.search.fib; local ext=$?
- if ((ext==0)); then
- _ble_edit_mark_active=insert
- ble/complete/dabbrev/.show-status.fib
- elif ((ext==148)); then
- ble/complete/dabbrev/.show-status.fib
- else
- ble/widget/.bell
- ble/widget/dabbrev/exit
- ble/complete/dabbrev/reset
- fib_kill=1
- fi
- return "$ext"
-}
-function ble/widget/dabbrev-expand {
- ble/complete/dabbrev/initialize-variables
- ble/decode/keymap/push dabbrev
- ble/util/fiberchain#initialize ble/complete/dabbrev
- ble/util/fiberchain#push next
- ble/util/fiberchain#resume
-}
-function ble/widget/dabbrev/next {
- ble/util/fiberchain#push next
- ble/util/fiberchain#resume
-}
-function ble/widget/dabbrev/prev {
- if ((${#_ble_util_fiberchain[@]})); then
- local ret; ble/array#pop _ble_util_fiberchain
- if ((${#_ble_util_fiberchain[@]})); then
- ble/util/fiberchain#resume
- else
- ble/complete/dabbrev/show-status
- fi
- elif ((${#_ble_complete_dabbrev_stack[@]})); then
- local ret; ble/array#pop _ble_complete_dabbrev_stack
- local rec str=${ret#*:}
- ble/string#split rec , "${ret%%:*}"
- ble-edit/content/reset-and-check-dirty "$str"
- _ble_edit_ind=${rec[2]}
- _ble_edit_mark=${rec[3]}
- _ble_complete_dabbrev_index=${rec[0]}
- _ble_complete_dabbrev_pos=${rec[1]}
- ble/complete/dabbrev/show-status
- else
- ble/widget/.bell
- return 1
- fi
-}
-function ble/widget/dabbrev/cancel {
- if ((${#_ble_util_fiberchain[@]})); then
- ble/util/fiberchain#clear
- ble/complete/dabbrev/show-status
- else
- ble/widget/dabbrev/exit
- ble/complete/dabbrev/reset
- fi
-}
-function ble/widget/dabbrev/exit {
- ble/decode/keymap/pop
- _ble_edit_mark_active=
- ble/complete/dabbrev/erase-status
-}
-function ble/widget/dabbrev/exit-default {
- ble/widget/dabbrev/exit
- ble/decode/widget/skip-lastwidget
- ble/decode/widget/redispatch-by-keys "${KEYS[@]}"
-}
-function ble/widget/dabbrev/accept-line {
- ble/widget/dabbrev/exit
- ble-decode-key 13
-}
-function ble-decode/keymap:dabbrev/define {
- ble-bind -f __default__ 'dabbrev/exit-default'
- ble-bind -f __line_limit__ nop
- ble-bind -f 'C-g' 'dabbrev/cancel'
- ble-bind -f 'C-x C-g' 'dabbrev/cancel'
- ble-bind -f 'C-M-g' 'dabbrev/cancel'
- ble-bind -f C-r 'dabbrev/next'
- ble-bind -f C-s 'dabbrev/prev'
- ble-bind -f RET 'dabbrev/exit'
- ble-bind -f C-m 'dabbrev/exit'
- ble-bind -f C-RET 'dabbrev/accept-line'
- ble-bind -f C-j 'dabbrev/accept-line'
-}
-function ble/complete/action:cdpath/initialize {
- DATA=$cdpath_basedir
- ble/complete/action:file/initialize
-}
-function ble/complete/action:cdpath/complete {
- CAND=$DATA$CAND ble/complete/action:file/complete
-}
-function ble/complete/action:cdpath/init-menu-item {
- ble/color/face2g cmdinfo_cd_cdpath; g=$ret
- if [[ :$comp_type: == *:vstat:* ]]; then
- if [[ -h $CAND ]]; then
- suffix='@'
- elif [[ -d $CAND ]]; then
- suffix='/'
- fi
- fi
-}
-function ble/complete/action:cdpath/get-desc {
- local sgr0=$_ble_term_sgr0 sgr1= sgr2=
- local g ret g1 g2
- ble/syntax/highlight/getg-from-filename "$DATA$CAND"; g1=$g
- [[ $g1 ]] || { ble/color/face2g filename_warning; g1=$ret; }
- ((g2=g1^_ble_color_gflags_Revert))
- ble/color/g2sgr "$g1"; sgr1=$ret
- ble/color/g2sgr "$g2"; sgr2=$ret
- ble/string#escape-for-display "$DATA$CAND" sgr1="$sgr2":sgr0="$sgr1"
- local filename=$sgr1$ret$sgr0
- CAND=$DATA$CAND ble/complete/action:file/get-desc
- desc="CDPATH $filename ($desc)"
-}
-function ble/cmdinfo/complete:cd/.impl {
- local type=$1
- [[ $comps_flags == *v* ]] || return 1
- if [[ $COMPV == -* ]]; then
- local action=word
- case $type in
- (pushd)
- if [[ $COMPV == - || $COMPV == -n ]]; then
- local "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- ble/complete/cand/yield "$action" -n
- fi ;;
- (*)
- COMP_PREFIX=$COMPV
- local -a list=()
- local "${_ble_complete_yield_varnames[@]/%/=}" # WA #D1570 safe
- ble/complete/cand/yield.initialize "$action"
- [[ $COMPV == -* ]] && ble/complete/cand/yield "$action" "${COMPV}"
- [[ $COMPV != *L* ]] && ble/complete/cand/yield "$action" "${COMPV}L"
- [[ $COMPV != *P* ]] && ble/complete/cand/yield "$action" "${COMPV}P"
- ((_ble_bash>=40200)) && [[ $COMPV != *e* ]] && ble/complete/cand/yield "$action" "${COMPV}e"
- ((_ble_bash>=40300)) && [[ $COMPV != *@* ]] && ble/complete/cand/yield "$action" "${COMPV}@" ;;
- esac
- return 0
- fi
- [[ :$comp_type: != *:[maA]:* && $COMPV =~ ^.+/ ]] && COMP_PREFIX=${BASH_REMATCH[0]}
- [[ :$comp_type: == *:[maA]:* && ! $COMPV ]] && return 1
- if [[ ! $CDPATH ]]; then
- ble/complete/source:dir
- return "$?"
- fi
- ble/complete/source:tilde; local ext=$?
- ((ext==148||ext==0)) && return "$ext"
- local is_pwd_visited= is_cdpath_generated=
- "${_ble_util_set_declare[@]//NAME/visited}" # WA #D1570 checked
- local name names; ble/string#split names : "$CDPATH"
- for name in "${names[@]}"; do
- [[ $name ]] || continue
- name=${name%/}/
- local action=cdpath
- [[ ${name%/} == . || ${name%/} == "${PWD%/}" ]] &&
- is_pwd_visited=1 action=file
- local -a candidates=()
- local ret cand
- ble/complete/source:file/.construct-pathname-pattern "$COMPV"
- ble/complete/util/eval-pathname-expansion "$name$ret"; (($?==148)) && return 148
- ble/complete/source/test-limit ${#ret[@]} || return 1
- for cand in "${ret[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) &&
- ble/complete/check-cancel && return 148
- [[ $cand && -d $cand ]] || continue
- [[ $cand == / ]] || cand=${cand%/}
- cand=${cand#"$name"}
- ble/set#contains visited "$cand" && continue
- ble/set#add visited "$cand"
- ble/array#push candidates "$cand"
- done
- ((${#candidates[@]})) || continue
- local flag_source_filter=1
- local cdpath_basedir=$name
- ble/complete/cand/yield-filenames "$action" "${candidates[@]}"
- [[ $action == cdpath ]] && is_cdpath_generated=1
- done
- [[ $is_cdpath_generated ]] &&
- bleopt complete_menu_style=desc
- if [[ ! $is_pwd_visited ]]; then
- local -a candidates=()
- local ret cand
- ble/complete/source:file/.construct-pathname-pattern "$COMPV"
- ble/complete/util/eval-pathname-expansion "${ret%/}/"; (($?==148)) && return 148
- ble/complete/source/test-limit ${#ret[@]} || return 1
- for cand in "${ret[@]}"; do
- ((cand_iloop++%bleopt_complete_polling_cycle==0)) &&
- ble/complete/check-cancel && return 148
- [[ -d $cand ]] || continue
- [[ $cand == / ]] || cand=${cand%/}
- ble/set#contains visited "$cand" && continue
- ble/array#push candidates "$cand"
- done
- local flag_source_filter=1
- ble/complete/cand/yield-filenames file "${candidates[@]}"
- fi
-}
-function ble/cmdinfo/complete:cd {
- ble/cmdinfo/complete:cd/.impl cd
-}
-function ble/cmdinfo/complete:pushd {
- ble/cmdinfo/complete:cd/.impl pushd
-}
-blehook/invoke complete_load
-blehook complete_load=
-return 0