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  }