fixed disp with escape sequence

This commit is contained in:
fatalerrors
2026-07-09 14:56:30 +02:00
parent e6607f07af
commit e328199618

View File

@@ -44,7 +44,7 @@ set_colors()
export DEFAULTFG='\e[0;39m'
export DEFAULTBG='\e[0;49m'
export DEFAULTCOL="${DEFAULTBG}${DEFAULTFG}"
export RESETCOL=$'\e[0m'
export RESETCOL='\e[0m'
# Regular Colors
export Black='\e[0;30m'
@@ -134,9 +134,8 @@ disp()
_disp_print_wrapped()
{
local prefix="$1"
local prefix_len="$2"
local target_fd="$3"
shift 3
local target_fd="$2"
shift 2
local message="$*"
local cols="${COLUMNS:-}"
@@ -145,14 +144,57 @@ disp()
fi
[[ -z "$cols" || ! "$cols" =~ ^[0-9]+$ || "$cols" -lt 20 ]] && cols=80
# Match ANSI CSI sequences in real-ESC, literal \e and literal \033 forms
# so their on-screen width (zero) is excluded from all width calculations.
local ansi_re=$'\e\\[[0-9;]*[A-Za-z]'
ansi_re+='|\\e\[[0-9;]*[A-Za-z]'
ansi_re+='|\\033\[[0-9;]*[A-Za-z]'
# The hanging-indent width is the prefix's VISIBLE length (ANSI stripped),
# so callers no longer need to pass a separate plain-text length.
local _pv=$prefix
while [[ $_pv =~ $ansi_re ]]; do _pv=${_pv/"${BASH_REMATCH[0]}"/}; done
local indent_len=0
[[ "$prefix_len" =~ ^[0-9]+$ && "$prefix_len" -gt 0 ]] && indent_len=$((prefix_len + 1))
(( ${#_pv} > 0 )) && indent_len=$(( ${#_pv} + 1 ))
local width=$((cols - indent_len))
(( width < 10 )) && width=10
local wrapped
wrapped=$(printf "%s" "$message" | fold -s -w "$width")
# ANSI-aware soft wrap (fold -s semantics): break at the last space that
# keeps a line within `width` VISIBLE columns, hard-breaking only when a
# run has no space. ANSI escapes are copied through at zero width so they
# no longer inflate the measured width and cause premature wrapping.
local wrapped="" line="" line_vis=0 last_space=-1
local _i=0 _n=${#message}
while (( _i < _n )); do
local _sub=${message:_i}
if [[ $_sub =~ ^($ansi_re) ]]; then
line+=${BASH_REMATCH[0]}
_i=$(( _i + ${#BASH_REMATCH[0]} ))
continue
fi
local _c=${message:_i:1}
_i=$(( _i + 1 ))
line+=$_c
(( line_vis++ ))
[[ $_c == ' ' ]] && last_space=${#line}
if (( line_vis > width )); then
if (( last_space > 0 )); then
wrapped+=${line:0:last_space-1}$'\n'
line=${line:last_space}
local _st=$line
while [[ $_st =~ $ansi_re ]]; do _st=${_st/"${BASH_REMATCH[0]}"/}; done
line_vis=${#_st}
else
local _keep=${line: -1}
wrapped+=${line:0:${#line}-1}$'\n'
line=$_keep
line_vis=1
fi
last_space=-1
fi
done
wrapped+=$line
local first_line=1
local line
@@ -188,50 +230,46 @@ disp()
case ${1^^} in
"I")
local heads_plain="[ info ]"
if [[ $color_enabled -eq 1 ]]; then
local heads="[ ${IGreen}info${DEFAULTFG} ]"
else
local heads="$heads_plain"
local heads="[ info ]"
fi
shift
[[ -z $QUIET || $QUIET -ne 1 ]] && \
_disp_print_wrapped "$heads" "${#heads_plain}" 1 "$*"
_disp_print_wrapped "$heads" 1 "$*"
;;
"W")
local heads_plain="[ Warning ]"
if [[ $color_enabled -eq 1 ]]; then
local heads="[ ${IYellow}Warning${DEFAULTFG} ]"
else
local heads="$heads_plain"
local heads="[ Warning ]"
fi
shift
_disp_print_wrapped "$heads" "${#heads_plain}" 2 "$*"
_disp_print_wrapped "$heads" 2 "$*"
;;
"E")
local heads_plain="[ ERROR ]"
if [[ $color_enabled -eq 1 ]]; then
local heads="[ ${IRed}ERROR${DEFAULTFG} ]"
else
local heads="$heads_plain"
local heads="[ ERROR ]"
fi
shift
_disp_print_wrapped "$heads" "${#heads_plain}" 2 "$*"
_disp_print_wrapped "$heads" 2 "$*"
;;
"D")
local heads_plain="[ debug ]"
if [[ $color_enabled -eq 1 ]]; then
local heads="[ ${ICyan}debug${DEFAULTFG} ]"
else
local heads="$heads_plain"
local heads="[ debug ]"
fi
shift
[[ -n $DEBUG && $DEBUG -gt 1 ]] && \
_disp_print_wrapped "$heads" "${#heads_plain}" 1 "$*"
_disp_print_wrapped "$heads" 1 "$*"
;;
* )
[[ -z $QUIET || $QUIET -ne 1 ]] && \
_disp_print_wrapped "" 0 1 "$*"
_disp_print_wrapped "" 1 "$*"
;;
esac
}