This commit is contained in:
anon 2025-01-04 02:58:09 +01:00
commit 631bcb4abe
12 changed files with 207 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.out
*.tags

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
bundle:
-mkdir object/.vim/
-mkdir ~/bin/
cp wrappers/* ~/bin/
install: bundle
tar -x -f errtags.tar --dereference -C ~/

26
README.md Normal file
View File

@ -0,0 +1,26 @@
# Errtags
## Idea
The normal way to do error reporting is redefining your build-system to vim.
Thats disguasting.
The right way should be to hook into the actual build system.
## Process
Make is our friend, because its hackable.
token := genrate-session-token()
foreach t in $tools do
$t($token)
done
The session token is a number used to differentiate between compiles.
Every tool is wrapped, so that it emits its output to both normally and piped into errtags.
Errtags is responsible for grepping error messages and storing them in a csv-like file.
The csv is passed to vim so it can display the errors.
## Dependencies
+ Tcl

4
debug/c_hw/Makefile Normal file
View File

@ -0,0 +1,4 @@
CFLAGS += -Wall -Wpedantic
main:
${CC} ${CFLAGS} main.c

1
debug/c_hw/header.h Normal file
View File

@ -0,0 +1 @@
int i = "asd";

26
debug/c_hw/main.c Normal file
View File

@ -0,0 +1,26 @@
// header name typo
//#include <studio.h>
// NOTE: LOL.
// you thought gcc can report syntax errors if preprocessing failed?
// LMAO EVEN.
#include "header.h"
// messed up struct syntax
struct {
int a,
int b;
} k;
int f(void) {
// statement with no effect
10 + 10;
// missing return statement
}
signed main(void) {
// non-sensical break
break;
return f();
}

39
errtags Executable file
View File

@ -0,0 +1,39 @@
#!/usr/bin/tclsh
set outputFilename "/home/anon/stow/.cache/errtags.tags"
set ERRTAGS_SESSION [expr { \
[info exists env(ERRTAGS_SESSION)] ? $env(ERRTAGS_SESSION) : "" \
}]
if {$ERRTAGS_SESSION eq ""} {
set ERRTAGS_SESSION [expr {int(rand() * 1000) + 1}]
}
# --- Setup output
proc getMode {fileName errtagsSession} {
if {[catch {set fileId [open $fileName r]}]} { return w }
set firstLine [gets $fileId]
close $fileId
return [expr {[string match "#$errtagsSession" $firstLine] ? "a" : "w"}]
}
set mode [getMode $outputFilename $ERRTAGS_SESSION]
set output [open $outputFilename $mode]
# --- Header rewrite
if {$mode == "w"} {
puts $output "#$ERRTAGS_SESSION"
}
# --- Error translation
set errex {(.+):(\d+):(\d+): error: (.*)}
while {[gets stdin line] >= 0} {
if {[regexp $errex $line ignore sfile sline scol msg]} {
puts $output "$sfile:$sline:$scol:$msg"
}
}
close $output

1
errtags.sh Normal file
View File

@ -0,0 +1 @@
alias make='make.sh CC=cc.sh'

90
errtags.vim Normal file
View File

@ -0,0 +1,90 @@
" --- Define our prop types ---
" #pragma region
call prop_type_delete('ErrorHighlight')
call prop_type_delete('CommentHighlight')
hi link ErrTagsError ErrorMsg
hi link ErrTagsMessage Comment
call prop_type_add('ErrorHighlight', {
\ 'highlight': 'ErrTagsError',
\ })
call prop_type_add('CommentHighlight', {
\ 'highlight': 'ErrTagsMessage',
\ })
" #pragma endregion
" --- Main logic ---
" #pragma region
function! AddNotice(lnum, col, message)
try
call prop_add(a:lnum, a:col, {
\ 'type': 'ErrorHighlight',
\ 'length': 1
\ })
catch /E964/ | endtry
call prop_add(a:lnum, 0, {
\ 'type': 'CommentHighlight',
\ 'text': ' # E: ' . a:message,
\ 'text_align': 'after'
\ })
endfunction
function AddNotices(notices)
for l:notice in a:notices
if l:notice['fname'] == expand('%:t')
call AddNotice(l:notice.lnum, l:notice.col, l:notice.text)
endif
endfor
endfunction
function! ParseNotices(lines)
let l:errors = []
for l:line in a:lines
let l:fields = split(l:line, ':')
if len(l:fields) >= 2
let l:filename = l:fields[0]
let l:line_number = l:fields[1]
let l:column_number = l:fields[2]
let l:message = join(l:fields[3:], ':')
call add(l:errors, {
\ 'fname': l:filename,
\ 'lnum': l:line_number,
\ 'col': l:column_number,
\ 'text': l:message,
\ 'type': 'E',
\ })
endif
endfor
return l:errors
endfunction
function! DoNotices()
call prop_remove({ 'type': 'ErrorHighlight' })
call prop_remove({ 'type': 'CommentHighlight' })
let l:lines = readfile(expand('~/stow/.cache/errtags.tags'))
let l:notices = ParseNotices(l:lines)
call AddNotices(l:notices)
endfunction
" #pragma endregion
let g:errtags_events = ["BufEnter", "BufWrite"]
" --- Hook up everything ---
" #pragma region
if exists('g:errtags_events')
for e in g:errtags_events
execute "autocmd " . e . " * DoNotices"
endfor
endif
command! DoNotices :call DoNotices()
" #pragma endregion

0
object/.gitkeep Normal file
View File

7
wrappers/cc.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
cc -fdiagnostics-color=always "$@" 2>&1 \
| tee >(\
sed -e 's/\x1b\[[0-9;]*m//g' -e 's/\x1b\[K//g' \
| errtags
)
exit ${PIPESTATUS[0]}

4
wrappers/make.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
ERRTAGS_SESSION=$RANDOM
export ERRTAGS_SESSION
make "$@"