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