1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 09:40:06 +08:00
SpaceVim/bundle/neomake/contrib/highlight-log
2020-06-13 14:06:35 +08:00

145 lines
4.8 KiB
Bash
Vendored
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# This script adds color highlighting to the output from Neomake's Vader tests
# (when called with "vader"), or to the file that gets written into according
# to `neomake_logfile`.
#
# You can use the following to watch colored logs in a terminal window, after
# having used `let g:neomake_logfile = '/tmp/neomake.log'` in Neovim/Vim:
#
# tail -f /tmp/neomake.log | /path/to/neomake/contrib/highlight-log
bold="" # $(tput bold)
bold_off=""
debug_color="" # $(tput dim), does not work in urxvt (although in infocmp/terminfo).
debug_color_off=""
color_off=""
log_color=""
log_color_off="$bold_off$color_off"
error_color=""
error_color_off="$bold_off$color_off"
# compact: display test headers, but not inner output for successful ones.
compact=0
while [ $# -ne 0 ]; do
case $1 in
--compact) compact=1; shift ;;
--) shift; break ;;
-?*) echo "Unknown option: $1" 1>&2; exit 64 ;;
*) break ;;
esac
done
if [ "$1" = vader ]; then
# Match non-log lines (i.e. keep output from :Log, which should cause
# all messages from a case to be visible).
# This should also ignore empty lines and lines starting with a character
# (e.g. via NVIM_LOG_FILE:=/dev/stderr, and from :echom).
re_log_line='^(.*( )? )(> .*)$'
re_ignore_log_line='^.*( )? > \[(debug |verbose|warning|error )|((D|V|W|E) +\+[.0-9]+)\]'
colorize() {
# Only colorize if stdout is connected to a tty (not with :!make).
if ! [ -t 1 ]; then
cat -
return
fi
# sed: add coloring to Vader's output:
# 1. failures (includes pending) in red "(X)"
# 2. test case header in bold "(2/2)"
# 3. Neomake's error log messages
# 4. Neomake's debug log messages
# 5. non-Neomake log lines (e.g. from :Log)
sed -E -e 's/^(([^ ].*)? +)\([ [:digit:]]+\/[[:digit:]]+\) \[[ [:alpha:]]+\] \(X\).*/'"$error_color"'\0'"$error_color_off"'/' \
-e 's/^(([^ ].*)? +)(\([ [:digit:]]+\/[[:digit:]]+\))/\1'"$bold"'\3'"$bold_off"'/' \
-e 's/^ +> \[(error |E \+[.[:digit:]]+)\]: .*/'"$bold"'\0'"$bold_off"'/' \
-e 's/^ +> \[(debug |D \+[.[:digit:]]+)\]: .*/'"$debug_color"'\0'"$debug_color_off"'/' \
-e '/'"$re_ignore_log_line"'/! s/'"$re_log_line"'/\1'"$log_color"'\3'"$log_color_off"'/'
}
if ((compact)); then
# Do not display output for successful tests (i.e. the log statements).
last_start_match=
# Match Vader header ("( 1/33) [EXECUTE] …"), but also if there is output
# from Vim, e.g. with ":colder".
re_vader_header='^([^ ].*)?\ +(\(\ *[0-9]+/[0-9]+\))'
filtering=0
finished_reading=0
stopped_filtering=0
while [ "$finished_reading" = 0 ]; do
if ! read -r; then
if [ -z "$REPLY" ]; then
break
finished_reading=1
fi
fi
if [[ "$REPLY" == *'Vader error:'* ]] || [[ "$REPLY" == 'Error'* ]] || [[ "$REPLY" == 'Traceback'* ]]; then
printf "\r" >&2
printf "%s\n" "$REPLY"
continue
fi
if (( stopped_filtering )); then
echo "$REPLY"
continue
fi
if [[ "$REPLY" == *'Starting Vader:'* ]]; then
echo "$REPLY"
elif [[ "$REPLY" == ' Duration: '* ]]; then
echo "$REPLY"
elif [[ "$REPLY" == *'(X)'* ]]; then
# Should also match "(1/1) [EXECUTE] (X) Error: Vim(function):E126: Missing :endfunction" already.
if [[ -n "$filtered" ]]; then
echo "$filtered"
fi
echo "$REPLY"
filtered=
filtering=0
elif [[ "$REPLY" =~ $re_vader_header ]]; then
filtering=1
if [[ ${BASH_REMATCH[2]} == "$last_start_match" ]]; then
filtered="$filtered"$'\n'"$REPLY"
else
echo "$REPLY"
filtered=
fi
last_start_match="${BASH_REMATCH[2]}"
elif [[ "$REPLY" == *'Success/Total: '* || "$REPLY" == ' Slowest tests:' ]]; then
echo "$REPLY"
filtering=0
filtered=
stopped_filtering=1
elif ! ((filtering)); then
echo "$REPLY"
elif [[ "$REPLY" =~ $re_log_line && ! "$REPLY" =~ $re_ignore_log_line ]]; then
if [[ "$REPLY" =~ '> SKIP:' ]]; then
echo "$REPLY"
continue
fi
if [[ -n "$filtered" ]]; then
echo "$filtered"
fi
echo "$REPLY"
filtered=
filtering=0
elif [[ -n "$filtered" ]]; then
filtered="$filtered"$'\n'"$REPLY"
else
filtered="$REPLY"
fi
done
else
cat -
fi | colorize
else
# Output from neomake_logfile.
error='^[:[:digit:]]\+ [[:digit:]]\+ \[E .*'
warn='^[:[:digit:]]\+ [[:digit:]]\+ \[W .*'
debug='^[:[:digit:]]\+ [[:digit:]]\+ \[D .*'
sed -e "s/$error/\0/" \
-e "s/$warn/w:\0/" \
-e "s/$debug/$debug_color\\0$debug_color_off/"
fi