You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							133 lines
						
					
					
						
							4.3 KiB
						
					
					
				
			
		
		
	
	
							133 lines
						
					
					
						
							4.3 KiB
						
					
					
				| # 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]/"$background" | |
|             elif [[ "$col" -eq 0 ]]; then | |
|                 zcurses attr "$win" "$colorpair" | |
|             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="-bold" || bold="+bold" | |
| [[ "$active_text" = "underline" || "$active_text" = "reverse" ]] || local active_text="reverse" | |
| # Linux has ncv 18, screen* has ncv 3 - underline won't work properly | |
| (( ${terminfo[ncv]:-0} & 2 )) && active_text="reverse" | |
| # FreeBSD uses TERM=xterm for newcons but doesn't actually support underline | |
| [[ "$TERM" = "xterm" && -z "$DISPLAY" ]] && 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" "$colorpair" | |
|  | |
| 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:
 | |
| 
 |