mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-04 10:57:50 +08:00
47 lines
1.1 KiB
Go
47 lines
1.1 KiB
Go
package util
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// PosError is an error associated with a position range.
|
|
type PosError struct {
|
|
Begin int
|
|
End int
|
|
Err error
|
|
}
|
|
|
|
func (pe *PosError) Error() string {
|
|
return fmt.Sprintf("%d-%d: %s", pe.Begin, pe.End, pe.msg())
|
|
}
|
|
|
|
// Pprint pretty-prints a PosError with a header indicating the source and type
|
|
// of the error, the error text and the affected line with an additional line
|
|
// that points an arrow at the affected column.
|
|
func (pe *PosError) Pprint(srcname, errtype, src string) string {
|
|
lineno, colno, line := FindContext(src, pe.Begin)
|
|
|
|
buf := new(bytes.Buffer)
|
|
// Source and type of the error
|
|
fmt.Fprintf(buf, "\033[1m%s:%d:%d: \033[31m%s:", srcname, lineno+1, colno+1, errtype)
|
|
// Message
|
|
fmt.Fprintf(buf, "\033[m\033[1m%s\033[m\n", pe.msg())
|
|
// Affected line
|
|
// TODO Handle long lines
|
|
fmt.Fprintf(buf, "%s\n", line)
|
|
// Column indicator
|
|
// TODO Handle multi-width characters
|
|
fmt.Fprintf(buf, "%s\033[32;1m^\033[m\n", strings.Repeat(" ", colno))
|
|
return buf.String()
|
|
}
|
|
|
|
func (pe *PosError) msg() string {
|
|
if pe.Err != nil {
|
|
return pe.Err.Error()
|
|
} else {
|
|
return "<nil>"
|
|
}
|
|
}
|