378 lines
9.3 KiB
Bash
378 lines
9.3 KiB
Bash
# Copy this file into /usr/share/zsh/site-functions/
|
|
# and add 'autoload n-list-input` to .zshrc
|
|
#
|
|
# This is an internal function not for direct use
|
|
|
|
emulate -L zsh
|
|
|
|
zmodload zsh/curses
|
|
|
|
setopt typesetsilent
|
|
|
|
# Compute first to show index
|
|
_nlist_compute_first_to_show_idx() {
|
|
from_what_idx_list_is_shown=0+((current_idx-1)/page_height)*page_height+1
|
|
}
|
|
|
|
_nlist_update_from_keywords() {
|
|
keywordisfresh="1"
|
|
if [ "$nkeywords" -gt 0 ]; then
|
|
curkeyword=$(( (curkeyword+1) % (nkeywords+1) ))
|
|
if [ "$curkeyword" -eq "0" ]; then
|
|
buffer=""
|
|
else
|
|
buffer="${keywords[curkeyword]}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
_nlist_iterate_theme() {
|
|
themeisfresh="1"
|
|
if [ "$1" = "1" ]; then
|
|
curtheme=$(( (curtheme+1) % (nthemes+1) ))
|
|
else
|
|
curtheme=curtheme-1
|
|
[ "$curtheme" -lt 0 ] && curtheme=nthemes
|
|
fi
|
|
|
|
if [ "$nthemes" -gt 0 ]; then
|
|
local theme=${themes[curtheme]}
|
|
[ "$curtheme" -eq "0" ] && theme="$backuptheme"
|
|
|
|
colorpair="${theme%/*}"
|
|
bold="${theme##*/}"
|
|
background="${colorpair#*/}"
|
|
zcurses bg main "$colorpair"
|
|
zcurses bg inner "$colorpair"
|
|
fi
|
|
}
|
|
|
|
_nlist_rotate_buffer() {
|
|
setopt localoptions noglob
|
|
|
|
local -a words
|
|
words=( ${(s: :)buffer} )
|
|
words=( ${words[-1]} ${words[1,-2]} )
|
|
|
|
local space=""
|
|
[ "${buffer[-1]}" = " " ] && space=" "
|
|
|
|
buffer="${(j: :)words}$space"
|
|
}
|
|
|
|
typeset -ga reply
|
|
reply=( -1 '' )
|
|
integer current_idx="$1"
|
|
integer from_what_idx_list_is_shown="$2"
|
|
integer page_height="$3"
|
|
integer page_width="$4"
|
|
integer last_element="$5"
|
|
integer hscroll="$6"
|
|
local key="$7"
|
|
integer search="$8"
|
|
local buffer="$9"
|
|
integer uniq_mode="$10"
|
|
integer f_mode="$11"
|
|
|
|
#
|
|
# Listening for input
|
|
#
|
|
|
|
if [ "$search" = "0" ]; then
|
|
|
|
case "$key" in
|
|
(UP|k|$'\C-P')
|
|
# Are there any elements before the current one?
|
|
[ "$current_idx" -gt 1 ] && current_idx=current_idx-1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(DOWN|j|$'\C-N')
|
|
# Are there any elements after the current one?
|
|
[ "$current_idx" -lt "$last_element" ] && current_idx=current_idx+1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(PPAGE|$'\b'|$'\C-?'|BACKSPACE)
|
|
current_idx=current_idx-page_height
|
|
[ "$current_idx" -lt 1 ] && current_idx=1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(NPAGE|" ")
|
|
current_idx=current_idx+page_height
|
|
[ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
($'\C-U')
|
|
current_idx=current_idx-page_height/2
|
|
[ "$current_idx" -lt 1 ] && current_idx=1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
($'\C-D')
|
|
current_idx=current_idx+page_height/2
|
|
[ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(HOME|g)
|
|
current_idx=1
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(END|G)
|
|
current_idx=last_element
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
($'\n'|ENTER)
|
|
# Is that element selectable?
|
|
# Check for this only when there is no search
|
|
if [[ "$NLIST_SEARCH_BUFFER" != "" || "$NLIST_IS_UNIQ_MODE" -eq 1 ||
|
|
${NLIST_NONSELECTABLE_ELEMENTS[(r)$current_idx]} != $current_idx ]]
|
|
then
|
|
# Save current element in the result variable
|
|
reply=( $current_idx "SELECT" )
|
|
fi
|
|
;;
|
|
(H|'?')
|
|
# This event needs to be enabled
|
|
if [[ "${NLIST_ENABLED_EVENTS[(r)HELP]}" = "HELP" ]]; then
|
|
reply=( -1 "HELP" )
|
|
fi
|
|
;;
|
|
(F1)
|
|
# This event needs to be enabled
|
|
if [[ "${NLIST_ENABLED_EVENTS[(r)F1]}" = "F1" ]]; then
|
|
reply=( -1 "$key" )
|
|
fi
|
|
;;
|
|
(F4|F5|F6|F7|F8|F9|F10|DC)
|
|
# ignore; F2, F3 are used below
|
|
;;
|
|
(q)
|
|
reply=( -1 "QUIT" )
|
|
;;
|
|
(/)
|
|
search=1
|
|
_nlist_cursor_visibility 1
|
|
;;
|
|
($'\t')
|
|
reply=( $current_idx "LEAVE" )
|
|
;;
|
|
($'\C-L')
|
|
reply=( -1 "REDRAW" )
|
|
;;
|
|
(\])
|
|
[[ "${(t)NLIST_HOP_INDEXES}" = "array" || "${(t)NLIST_HOP_INDEXES}" = "array-local" ]] &&
|
|
[ -z "$NLIST_SEARCH_BUFFER" ] && [ "$NLIST_IS_UNIQ_MODE" -eq 0 ] &&
|
|
for idx in "${(n)NLIST_HOP_INDEXES[@]}"; do
|
|
if [ "$idx" -gt "$current_idx" ]; then
|
|
current_idx=$idx
|
|
_nlist_compute_first_to_show_idx
|
|
break
|
|
fi
|
|
done
|
|
;;
|
|
(\[)
|
|
[[ "${(t)NLIST_HOP_INDEXES}" = "array" || "${(t)NLIST_HOP_INDEXES}" = "array-local" ]] &&
|
|
[ -z "$NLIST_SEARCH_BUFFER" ] && [ "$NLIST_IS_UNIQ_MODE" -eq 0 ] &&
|
|
for idx in "${(nO)NLIST_HOP_INDEXES[@]}"; do
|
|
if [ "$idx" -lt "$current_idx" ]; then
|
|
current_idx=$idx
|
|
_nlist_compute_first_to_show_idx
|
|
break
|
|
fi
|
|
done
|
|
;;
|
|
('<'|'{'|LEFT|'h')
|
|
hscroll=hscroll-7
|
|
[ "$hscroll" -lt 0 ] && hscroll=0
|
|
;;
|
|
('>'|'}'|RIGHT|'l')
|
|
hscroll+=7
|
|
;;
|
|
($'\E')
|
|
buffer=""
|
|
;;
|
|
(F3)
|
|
if [ "$search" = "1" ]; then
|
|
search=0
|
|
_nlist_cursor_visibility 0
|
|
else
|
|
search=1
|
|
_nlist_cursor_visibility 1
|
|
fi
|
|
;;
|
|
(o|$'\C-O')
|
|
uniq_mode=1-uniq_mode
|
|
;;
|
|
(f|$'\C-F')
|
|
(( f_mode=(f_mode+1) % 3 ))
|
|
;;
|
|
($'\x1F'|F2|$'\C-X')
|
|
search=1
|
|
_nlist_cursor_visibility 1
|
|
_nlist_update_from_keywords
|
|
;;
|
|
($'\C-T')
|
|
_nlist_iterate_theme 1
|
|
;;
|
|
($'\C-G')
|
|
_nlist_iterate_theme 0
|
|
;;
|
|
($'\C-E'|e)
|
|
# This event needs to be enabled
|
|
if [[ "${NLIST_ENABLED_EVENTS[(r)EDIT]}" = "EDIT" ]]; then
|
|
reply=( -1 "EDIT" )
|
|
fi
|
|
;;
|
|
($'\C-A')
|
|
_nlist_rotate_buffer
|
|
;;
|
|
(*)
|
|
;;
|
|
esac
|
|
|
|
else
|
|
|
|
case "$key" in
|
|
($'\n'|ENTER)
|
|
if [ "$NLIST_INSTANT_SELECT" = "1" ]; then
|
|
if [[ "$NLIST_SEARCH_BUFFER" != "" || "$NLIST_IS_UNIQ_MODE" -eq 1 ||
|
|
${NLIST_NONSELECTABLE_ELEMENTS[(r)$current_idx]} != $current_idx ]]
|
|
then
|
|
reply=( $current_idx "SELECT" )
|
|
fi
|
|
else
|
|
search=0
|
|
_nlist_cursor_visibility 0
|
|
fi
|
|
;;
|
|
($'\C-L')
|
|
reply=( -1 "REDRAW" )
|
|
;;
|
|
|
|
#
|
|
# Slightly limited navigation
|
|
#
|
|
|
|
(UP|$'\C-P')
|
|
[ "$current_idx" -gt 1 ] && current_idx=current_idx-1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(DOWN|$'\C-N')
|
|
[ "$current_idx" -lt "$last_element" ] && current_idx=current_idx+1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(PPAGE)
|
|
current_idx=current_idx-page_height
|
|
[ "$current_idx" -lt 1 ] && current_idx=1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(NPAGE)
|
|
current_idx=current_idx+page_height
|
|
[ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
($'\C-U')
|
|
current_idx=current_idx-page_height/2
|
|
[ "$current_idx" -lt 1 ] && current_idx=1;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
($'\C-D')
|
|
current_idx=current_idx+page_height/2
|
|
[ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(HOME)
|
|
current_idx=1
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(END)
|
|
current_idx=last_element
|
|
_nlist_compute_first_to_show_idx
|
|
;;
|
|
(LEFT)
|
|
hscroll=hscroll-7
|
|
[ "$hscroll" -lt 0 ] && hscroll=0
|
|
;;
|
|
(RIGHT)
|
|
hscroll+=7
|
|
;;
|
|
(F1)
|
|
# This event needs to be enabled
|
|
if [[ "${NLIST_ENABLED_EVENTS[(r)F1]}" = "F1" ]]; then
|
|
reply=( -1 "$key" )
|
|
fi
|
|
;;
|
|
(F4|F5|F6|F7|F8|F9|F10|DC)
|
|
# ignore; F2, F3 are used below
|
|
;;
|
|
|
|
#
|
|
# The input
|
|
#
|
|
|
|
($'\b'|$'\C-?'|BACKSPACE)
|
|
buffer="${buffer%?}"
|
|
;;
|
|
($'\C-W')
|
|
[ "$buffer" = "${buffer% *}" ] && buffer="" || buffer="${buffer% *}"
|
|
;;
|
|
($'\C-K')
|
|
buffer=""
|
|
;;
|
|
($'\E')
|
|
buffer=""
|
|
search=0
|
|
_nlist_cursor_visibility 0
|
|
;;
|
|
(F3)
|
|
if [ "$search" = "1" ]; then
|
|
search=0
|
|
_nlist_cursor_visibility 0
|
|
else
|
|
search=1
|
|
_nlist_cursor_visibility 1
|
|
fi
|
|
;;
|
|
($'\C-O')
|
|
uniq_mode=1-uniq_mode
|
|
;;
|
|
($'\C-F')
|
|
(( f_mode=(f_mode+1) % 3 ))
|
|
;;
|
|
($'\x1F'|F2|$'\C-X')
|
|
_nlist_update_from_keywords
|
|
;;
|
|
($'\C-T')
|
|
_nlist_iterate_theme 1
|
|
;;
|
|
($'\C-G')
|
|
_nlist_iterate_theme 0
|
|
;;
|
|
($'\C-E')
|
|
# This event needs to be enabled
|
|
if [[ "${NLIST_ENABLED_EVENTS[(r)EDIT]}" = "EDIT" ]]; then
|
|
reply=( -1 "EDIT" )
|
|
fi
|
|
;;
|
|
($'\C-A')
|
|
_nlist_rotate_buffer
|
|
;;
|
|
(*)
|
|
if [[ $#key == 1 && $((#key)) -lt 31 ]]; then
|
|
# ignore all other control keys
|
|
else
|
|
buffer+="$key"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
fi
|
|
|
|
reply[3]="$current_idx"
|
|
reply[4]="$from_what_idx_list_is_shown"
|
|
reply[5]="$hscroll"
|
|
reply[6]="$search"
|
|
reply[7]="$buffer"
|
|
reply[8]="$uniq_mode"
|
|
reply[9]="$f_mode"
|
|
|
|
# vim: set filetype=zsh:
|