2020-02-03 22:53:28 +03:00
|
|
|
declare-option -docstring %{
|
|
|
|
shell command to which the path of a copy of the current buffer will be passed
|
|
|
|
The output returned by this command is expected to comply with the following format:
|
|
|
|
{filename}:{line}:{column}: {kind}: {message}
|
|
|
|
} str lintcmd
|
2016-10-11 19:34:11 +03:00
|
|
|
|
2017-11-03 10:34:41 +03:00
|
|
|
declare-option -hidden line-specs lint_flags
|
|
|
|
declare-option -hidden range-specs lint_errors
|
2018-05-26 13:06:11 +03:00
|
|
|
declare-option -hidden int lint_error_count
|
|
|
|
declare-option -hidden int lint_warning_count
|
2016-10-11 19:34:11 +03:00
|
|
|
|
2017-11-03 10:34:41 +03:00
|
|
|
define-command lint -docstring 'Parse the current buffer with a linter' %{
|
2018-05-07 00:29:52 +03:00
|
|
|
evaluate-commands %sh{
|
2018-07-18 14:16:05 +03:00
|
|
|
if [ -z "${kak_opt_lintcmd}" ]; then
|
2019-11-14 10:32:55 +03:00
|
|
|
echo 'fail The `lintcmd` option is not set'
|
2018-07-18 14:16:05 +03:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2019-05-23 22:52:57 +03:00
|
|
|
filename="${kak_buffile##*/}"
|
2018-07-30 13:06:39 +03:00
|
|
|
|
2017-06-09 14:05:31 +03:00
|
|
|
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-lint.XXXXXXXX)
|
2016-10-11 19:34:11 +03:00
|
|
|
mkfifo "$dir"/fifo
|
2019-05-23 22:52:57 +03:00
|
|
|
printf '%s\n' "evaluate-commands -no-hooks write -sync $dir/${filename}"
|
2016-10-11 19:34:11 +03:00
|
|
|
|
2017-11-03 11:09:45 +03:00
|
|
|
printf '%s\n' "evaluate-commands -draft %{
|
2017-03-08 22:33:25 +03:00
|
|
|
edit! -fifo $dir/fifo -debug *lint-output*
|
2017-11-03 10:34:41 +03:00
|
|
|
set-option buffer filetype make
|
|
|
|
set-option buffer make_current_error_line 0
|
2018-08-19 01:04:31 +03:00
|
|
|
hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r '$dir' } }
|
2016-10-11 19:34:11 +03:00
|
|
|
}"
|
|
|
|
|
2019-06-10 19:25:51 +03:00
|
|
|
({ # do the parsing in the background and when ready send to the session
|
2016-10-11 19:34:11 +03:00
|
|
|
|
2019-05-23 22:52:57 +03:00
|
|
|
eval "$kak_opt_lintcmd '$dir'/${filename}" | sort -t: -k2,2 -n > "$dir"/stderr
|
2016-10-11 19:34:11 +03:00
|
|
|
|
|
|
|
# Flags for the gutter:
|
2018-06-21 01:46:38 +03:00
|
|
|
# stamp l3|{red}█ l11|{yellow}█
|
2016-10-11 19:34:11 +03:00
|
|
|
# Contextual error messages:
|
2018-06-21 01:46:38 +03:00
|
|
|
# stamp 'l1.c1,l1.c1|kind:message' 'l2.c2,l2.c2|kind:message'
|
2018-05-26 13:06:11 +03:00
|
|
|
awk -F: -v file="$kak_buffile" -v stamp="$kak_timestamp" -v client="$kak_client" '
|
|
|
|
BEGIN {
|
|
|
|
error_count = 0
|
|
|
|
warning_count = 0
|
|
|
|
}
|
2018-08-02 14:20:16 +03:00
|
|
|
/:[1-9][0-9]*:[1-9][0-9]*: ([Ff]atal )?[Ee]rror/ {
|
2018-06-21 01:46:38 +03:00
|
|
|
flags = flags " " $2 "|{red}█"
|
2018-05-26 13:06:11 +03:00
|
|
|
error_count++
|
2016-10-11 19:34:11 +03:00
|
|
|
}
|
2018-08-02 14:20:16 +03:00
|
|
|
/:[1-9][0-9]*:[1-9][0-9]*:/ {
|
2016-10-11 19:34:11 +03:00
|
|
|
if ($4 !~ /[Ee]rror/) {
|
2018-06-21 01:46:38 +03:00
|
|
|
flags = flags " " $2 "|{yellow}█"
|
2018-05-26 13:06:11 +03:00
|
|
|
warning_count++
|
2016-10-11 19:34:11 +03:00
|
|
|
}
|
|
|
|
}
|
2018-08-02 14:20:16 +03:00
|
|
|
/:[1-9][0-9]*:[1-9][0-9]*:/ {
|
2018-05-24 20:36:32 +03:00
|
|
|
kind = substr($4, 2)
|
2018-06-21 01:46:38 +03:00
|
|
|
error = $2 "." $3 "," $2 "." $3 "|" kind
|
2018-07-20 13:18:33 +03:00
|
|
|
msg = ""
|
2018-05-24 20:36:32 +03:00
|
|
|
# fix case where $5 is not the last field because of extra colons in the message
|
2018-07-20 13:18:33 +03:00
|
|
|
for (i=5; i<=NF; i++) msg = msg ":" $i
|
|
|
|
gsub(/\|/, "\\|", msg)
|
|
|
|
gsub("'\''", "'"''"'", msg)
|
|
|
|
error = error msg " (col " $3 ")"
|
2018-06-21 01:46:38 +03:00
|
|
|
errors = errors " '\''" error "'\''"
|
2016-10-11 19:34:11 +03:00
|
|
|
}
|
|
|
|
END {
|
2018-06-21 01:46:38 +03:00
|
|
|
print "set-option \"buffer=" file "\" lint_flags " stamp flags
|
2016-11-01 23:31:24 +03:00
|
|
|
gsub("~", "\\~", errors)
|
2018-06-21 01:46:38 +03:00
|
|
|
print "set-option \"buffer=" file "\" lint_errors " stamp errors
|
2018-05-26 13:06:11 +03:00
|
|
|
print "set-option \"buffer=" file "\" lint_error_count " error_count
|
|
|
|
print "set-option \"buffer=" file "\" lint_warning_count " warning_count
|
|
|
|
print "evaluate-commands -client " client " lint-show-counters"
|
2016-10-11 19:34:11 +03:00
|
|
|
}
|
|
|
|
' "$dir"/stderr | kak -p "$kak_session"
|
|
|
|
|
2018-08-02 14:20:16 +03:00
|
|
|
cut -d: -f2- "$dir"/stderr | awk -v bufname="${kak_bufname}" '
|
|
|
|
/^[1-9][0-9]*:[1-9][0-9]*:/ {
|
|
|
|
print bufname ":" $0
|
|
|
|
}
|
|
|
|
' > "$dir"/fifo
|
2016-10-11 19:34:11 +03:00
|
|
|
|
2019-06-10 19:25:51 +03:00
|
|
|
} & ) >/dev/null 2>&1 </dev/null
|
2016-10-11 19:34:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-03 10:34:41 +03:00
|
|
|
define-command -hidden lint-show %{
|
2017-05-25 21:31:56 +03:00
|
|
|
update-option buffer lint_errors
|
2018-05-07 00:29:52 +03:00
|
|
|
evaluate-commands %sh{
|
2019-06-19 15:59:42 +03:00
|
|
|
eval "set -- ${kak_quoted_opt_lint_errors}"
|
2018-07-18 17:34:35 +03:00
|
|
|
shift
|
|
|
|
|
|
|
|
s=""
|
|
|
|
for i in "$@"; do
|
|
|
|
s="${s}
|
|
|
|
${i}"
|
|
|
|
done
|
|
|
|
|
|
|
|
printf %s\\n "${s}" | awk -v line="${kak_cursor_line}" \
|
|
|
|
-v column="${kak_cursor_column}" \
|
|
|
|
"/^${kak_cursor_line}\./"' {
|
2018-12-13 10:42:52 +03:00
|
|
|
gsub(/"|%/, "&&")
|
2018-07-18 17:34:35 +03:00
|
|
|
msg = substr($0, index($0, "|"))
|
|
|
|
sub(/^[^ \t]+[ \t]+/, "", msg)
|
|
|
|
printf "info -anchor %d.%d \"%s\"\n", line, column, msg
|
|
|
|
}'
|
|
|
|
}
|
|
|
|
}
|
2016-10-11 19:34:11 +03:00
|
|
|
|
2018-05-26 13:06:11 +03:00
|
|
|
define-command -hidden lint-show-counters %{
|
|
|
|
echo -markup linting results:{red} %opt{lint_error_count} error(s){yellow} %opt{lint_warning_count} warning(s)
|
|
|
|
}
|
|
|
|
|
2017-11-03 10:34:41 +03:00
|
|
|
define-command lint-enable -docstring "Activate automatic diagnostics of the code" %{
|
2018-07-08 12:11:04 +03:00
|
|
|
add-highlighter window/lint flag-lines default lint_flags
|
2016-10-11 19:34:11 +03:00
|
|
|
hook window -group lint-diagnostics NormalIdle .* %{ lint-show }
|
2018-02-11 14:02:53 +03:00
|
|
|
hook window -group lint-diagnostics WinSetOption lint_flags=.* %{ info; lint-show }
|
2016-10-11 19:34:11 +03:00
|
|
|
}
|
|
|
|
|
2017-11-03 10:34:41 +03:00
|
|
|
define-command lint-disable -docstring "Disable automatic diagnostics of the code" %{
|
2018-07-07 02:51:18 +03:00
|
|
|
remove-highlighter window/lint
|
2017-01-04 03:07:45 +03:00
|
|
|
remove-hooks window lint-diagnostics
|
2016-10-11 19:34:11 +03:00
|
|
|
}
|
|
|
|
|
2017-11-03 10:34:41 +03:00
|
|
|
define-command lint-next-error -docstring "Jump to the next line that contains an error" %{
|
2017-05-25 21:31:56 +03:00
|
|
|
update-option buffer lint_errors
|
2018-07-18 15:48:34 +03:00
|
|
|
|
2018-05-07 00:29:52 +03:00
|
|
|
evaluate-commands %sh{
|
2019-06-19 15:59:42 +03:00
|
|
|
eval "set -- ${kak_quoted_opt_lint_errors}"
|
2018-07-18 15:48:34 +03:00
|
|
|
shift
|
|
|
|
|
|
|
|
for i in "$@"; do
|
|
|
|
candidate="${i%%|*}"
|
|
|
|
if [ "${candidate%%.*}" -gt "${kak_cursor_line}" ]; then
|
|
|
|
range="${candidate}"
|
|
|
|
break
|
2016-10-11 19:34:11 +03:00
|
|
|
fi
|
2018-07-18 15:48:34 +03:00
|
|
|
done
|
|
|
|
|
|
|
|
range="${range-${1%%|*}}"
|
|
|
|
if [ -n "${range}" ]; then
|
|
|
|
printf 'select %s\n' "${range}"
|
|
|
|
else
|
2019-11-14 10:32:55 +03:00
|
|
|
echo 'fail no lint diagnostics'
|
2018-07-18 15:48:34 +03:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
}
|
2016-11-02 15:42:35 +03:00
|
|
|
|
2017-11-03 10:34:41 +03:00
|
|
|
define-command lint-previous-error -docstring "Jump to the previous line that contains an error" %{
|
2017-05-25 21:31:56 +03:00
|
|
|
update-option buffer lint_errors
|
2018-07-18 15:48:34 +03:00
|
|
|
|
2018-05-07 00:29:52 +03:00
|
|
|
evaluate-commands %sh{
|
2019-06-19 15:59:42 +03:00
|
|
|
eval "set -- ${kak_quoted_opt_lint_errors}"
|
2018-07-18 15:48:34 +03:00
|
|
|
shift
|
|
|
|
|
|
|
|
for i in "$@"; do
|
|
|
|
candidate="${i%%|*}"
|
|
|
|
|
|
|
|
if [ "${candidate%%.*}" -ge "${kak_cursor_line}" ]; then
|
|
|
|
range="${last_candidate}"
|
|
|
|
break
|
2016-11-02 15:42:35 +03:00
|
|
|
fi
|
2018-07-18 15:48:34 +03:00
|
|
|
|
|
|
|
last_candidate="${candidate}"
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ $# -ge 1 ]; then
|
|
|
|
shift $(($# - 1))
|
|
|
|
range="${range:-${1%%|*}}"
|
|
|
|
printf 'select %s\n' "${range}"
|
|
|
|
else
|
2019-11-14 10:32:55 +03:00
|
|
|
echo 'fail no lint diagnostics'
|
2018-07-18 15:48:34 +03:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
}
|