github.com/hoop33/elvish@v0.0.0-20160801152013-6d25485beab4/util/pos_error.go (about) 1 package util 2 3 import ( 4 "bytes" 5 "fmt" 6 "strings" 7 ) 8 9 // PosError is an error associated with a position range. 10 type PosError struct { 11 Begin int 12 End int 13 Err error 14 } 15 16 func (pe *PosError) Error() string { 17 return fmt.Sprintf("%d-%d: %s", pe.Begin, pe.End, pe.msg()) 18 } 19 20 // Pprint pretty-prints a PosError with a header indicating the source and type 21 // of the error, the error text and the affected line with an additional line 22 // that points an arrow at the affected column. 23 func (pe *PosError) Pprint(srcname, errtype, src string) string { 24 lineno, colno, line := FindContext(src, pe.Begin) 25 26 buf := new(bytes.Buffer) 27 // Source and type of the error 28 fmt.Fprintf(buf, "\033[1m%s:%d:%d: \033[31m%s: ", srcname, lineno+1, colno+1, errtype) 29 // Message 30 fmt.Fprintf(buf, "\033[m\033[1m%s\033[m\n", pe.msg()) 31 // Affected line 32 // TODO Handle long lines 33 fmt.Fprintf(buf, "%s\n", line) 34 // Column indicator 35 // TODO Handle multi-width characters 36 fmt.Fprintf(buf, "%s\033[32;1m^\033[m\n", strings.Repeat(" ", colno)) 37 return buf.String() 38 } 39 40 func (pe *PosError) msg() string { 41 if pe.Err != nil { 42 return pe.Err.Error() 43 } else { 44 return "<nil>" 45 } 46 }