Parent directory

n-list-draw

4374 bytes
  1# Copy this file into /usr/share/zsh/site-functions/
  2# and add 'autoload n-list-draw` to .zshrc
  3#
  4# This is an internal function not for direct use
  5
  6emulate -L zsh
  7
  8zmodload zsh/curses
  9
 10setopt typesetsilent extendedglob
 11
 12_nlist_print_with_ansi() {
 13    local win="$1" text="$2" out col chunk Xout
 14    integer text_offset="$3" max_text_len="$4" text_len=0 no_match=0 nochunk_text_len to_skip_from_chunk to_chop_off_from_chunk before_len
 15
 16    # 1 - non-escaped text, 2 - first number in the escaped text, with ;
 17    # 3 - second number, 4 - text after whole escape text
 18
 19    typeset -a c
 20    c=( black red green yellow blue magenta cyan white )
 21
 22    while [[ -n "$text" && "$no_match" -eq 0 ]]; do
 23        if [[ "$text" = (#b)([^$'\x1b']#)$'\x1b'\[([0-9](#c0,2))(#B)(\;|)(#b)([0-9](#c0,2))m(*) ]]; then
 24            # Text for further processing
 25            text="$match[4]"
 26            # Text chunk to output now
 27            out="$match[1]"
 28            # Save color
 29            col="$match[2]"
 30            (( match[3] >= 30 && match[3] <= 37 )) && col="$match[3]"
 31        else
 32            out="$text"
 33            no_match=1
 34        fi
 35
 36        if [ -n "$out" ]; then
 37################ Expand tabs ################
 38            chunk="$out"
 39            before_len="$text_len"
 40            Xout=""
 41
 42            while [ -n "$chunk" ]; do
 43                [[ "$chunk" = (#b)([^$'\t']#)$'\t'(*) ]] && {
 44                    (( all_text_len=((before_len+${#match[1]})/8+1)*8 ))
 45
 46                    Xout+="${(r:all_text_len-before_len:: :)match[1]}"
 47
 48                    before_len+=all_text_len-before_len
 49                    chunk="$match[2]"
 50                } || {
 51                    Xout+="$chunk"
 52                    break
 53                }
 54            done
 55#############################################
 56
 57            # Input text length without the current chunk
 58            nochunk_text_len=text_len
 59            # Input text length up to current chunk
 60            text_len+="$#Xout"
 61
 62            # Should start displaying with this chunk?
 63            # I.e. stop skipping left part of the input text?
 64            if (( text_len > text_offset )); then
 65                to_skip_from_chunk=text_offset-nochunk_text_len
 66
 67                # LEFT - is chunk off the left skip boundary? +1 for 1-based index in string
 68                (( to_skip_from_chunk > 0 )) && Xout="${Xout[to_skip_from_chunk+1,-1]}"
 69
 70                # RIGHT - is text off the screen?
 71                if (( text_len-text_offset > max_text_len )); then
 72                    to_chop_off_from_chunk=0+(text_len-text_offset)-max_text_len
 73                    Xout="${Xout[1,-to_chop_off_from_chunk-1]}"
 74                fi
 75                
 76                [ -n "$Xout" ] && zcurses string "$win" "$Xout"
 77            fi
 78        fi
 79
 80        if (( no_match == 0 )); then
 81            if (( col >= 30 && col <= 37 )); then
 82                zcurses attr "$win" $c[col-29]/"$background"
 83            elif [[ "$col" -eq 0 ]]; then
 84                zcurses attr "$win" "$colorpair"
 85            fi
 86        fi
 87    done
 88}
 89
 90integer highlight="$1"
 91integer page_height="$2"
 92integer page_width="$3"
 93local y_offset="$4"
 94local x_offset="$5"
 95local text_offset="$6"
 96local win="$7"
 97shift 7
 98integer max_text_len=page_width-x_offset
 99
100[[ "$bold" = "0" || "$bold" = "-bold" ]] && bold="-bold" || bold="+bold"
101[[ "$active_text" = "underline" || "$active_text" = "reverse" ]] || local active_text="reverse"
102# Linux has ncv 18, screen* has ncv 3 - underline won't work properly
103(( ${terminfo[ncv]:-0} & 2 )) && active_text="reverse"
104# FreeBSD uses TERM=xterm for newcons but doesn't actually support underline
105[[ "$TERM" = "xterm" && -z "$DISPLAY" ]] && active_text="reverse"
106
107integer max_idx=page_height
108integer end_idx=max_idx
109[ "$end_idx" -gt "$#" ] && end_idx="$#"
110integer y=y_offset
111
112zcurses attr "$win" "$bold" "$colorpair"
113
114integer i text_len
115local text
116for (( i=1; i<=end_idx; i++ )); do
117    zcurses move "$win" $y "$x_offset"
118
119    [ "$i" = "$highlight" ] && zcurses attr "$win" +"$active_text"
120    _nlist_print_with_ansi "$win" "$@[i]" "$text_offset" "$max_text_len"
121    zcurses clear "$win" eol
122    [ "$i" = "$highlight" ] && zcurses attr "$win" -"$active_text"
123
124    y+=1
125done
126
127if [ "$end_idx" -lt "$max_idx" ]; then
128    zcurses move "$win" $y "$x_offset"
129    zcurses clear "$win" eol
130fi
131
132zcurses attr "$win" white/black
133# vim: set filetype=zsh: