elvish/util/pos_error.go

47 lines
1.1 KiB
Go
Raw Normal View History

package util
2016-02-06 07:08:39 +08:00
2016-02-20 00:46:21 +08:00
import (
"bytes"
"fmt"
"strings"
)
2016-02-06 07:08:39 +08:00
2016-02-08 06:23:16 +08:00
// PosError is an error associated with a position range.
2016-02-06 07:08:39 +08:00
type PosError struct {
Begin int
End int
Err error
}
func (pe *PosError) Error() string {
2016-02-20 07:48:13 +08:00
return fmt.Sprintf("%d-%d: %s", pe.Begin, pe.End, pe.msg())
2016-02-06 07:08:39 +08:00
}
2016-02-20 00:46:21 +08:00
// 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
2016-02-20 07:48:13 +08:00
fmt.Fprintf(buf, "\033[m\033[1m%s\033[m\n", pe.msg())
2016-02-20 00:46:21 +08:00
// 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()
}
2016-02-20 07:48:13 +08:00
func (pe *PosError) msg() string {
if pe.Err != nil {
return pe.Err.Error()
} else {
return "<nil>"
}
}