# 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 } 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" # # 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 ;; (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="" ;; (o|$'\C-O') uniq_mode=1-uniq_mode ;; (*) ;; esac else case "$key" in ($'\n'|ENTER) search=0 _nlist_cursor_visibility 0 ;; ($'\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|F2|F3|F4|F5|F6|F7|F8|F9|F10) # ignore ;; # # 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 ;; ($'\C-O') uniq_mode=1-uniq_mode ;; (*) 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" # vim: set filetype=zsh: