diag

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 12 Imported by: 0

README

diag 🩺

Terminal diagnostic messages with source code context for Go.

Release Build Test Go Reference Go Report Card

Examples

Install

go get github.com/nuvrel/diag

Usage

Build each diagnostic separately, then hand them all to the printer at once. Print accepts any number of diagnostics and renders them in order, with spacing between each one.

src := []byte(`func add(a, b int) int {
	return a + c
}`)

d := diag.NewError("undefined: c").
	Code("E001").
	Detail(
		"Variables must be declared before use. The identifier `c` was not found in any enclosing scope.",
		"If you meant to use `b`, note that it was declared in the same function signature.",
	).
	Snippet(diag.NewSnippet(src).
		File("math.go").
		From(2, 13).
		To(2, 14).
		Message("c is not defined")).
	Help("did you mean to use b?")

p := diag.NewPrinter(os.Stdout, diag.DefaultConfig())

if err := p.Print(d); err != nil {
	return fmt.Errorf("printing diagnostics: %w", err)
}

Config

The Config struct controls every aspect of the output. Use the Default* helpers for the parts you want to keep as-is and override only what you need.

cfg := diag.Config{
	Profile:        colorprofile.Detect(os.Stdout, os.Environ()),
	Theme:          diag.DefaultTheme(),
	Characters:     diag.DefaultCharacters(),
	Prefixes:       diag.DefaultPrefixes(),
	SeverityLabels: diag.DefaultSeverityLabels(),
	DetailPad:      2,
}

Profile

Controls color output. Detected automatically from the terminal by default. Set to colorprofile.Ascii or colorprofile.NoTTY to disable colors:

cfg := diag.Config{
	Profile: colorprofile.Ascii,
	// ...
}

Theme

Controls the style of every visual element. All fields accept a lipgloss.Style:

cfg := diag.Config{
	// ...
	Theme: diag.Theme{
		Error:   lipgloss.NewStyle().Foreground(lipgloss.Color("#EB4268")).Bold(true),
		Warning: lipgloss.NewStyle().Foreground(lipgloss.Color("#E8FE96")).Bold(true),
		Message: lipgloss.NewStyle().Bold(true),
		Detail:  lipgloss.NewStyle().Foreground(lipgloss.Color("#CCCCCC")),
		Help:    lipgloss.NewStyle().Foreground(lipgloss.Color("#00D7FF")),
		Note:    lipgloss.NewStyle().Foreground(lipgloss.Color("#858392")),
		Muted:   lipgloss.NewStyle().Foreground(lipgloss.Color("#858392")),
	},
}

Characters

Controls every character used in the output. Defaults use Unicode box-drawing characters and symbols. Swap to ASCII alternatives for environments that cannot render Unicode:

cfg := diag.Config{
	// ...
	Characters: diag.Characters{
		Top:      ",",
		Mid:      "|",
		Bot:      "'",
		Dash:     "-",
		Dot:      ".",
		HintHelp: ">",
		HintNote: "~",
	},
}

HintHelp and HintNote are prepended to help and note lines. Set either to "" to remove the prefix character entirely.

Prefixes

Controls the label text for help and note lines:

cfg := diag.Config{
	// ...
	Prefixes: diag.Prefixes{
		Help: "ajuda",
		Note: "observação",
	},
}

SeverityLabels

Controls the label text for each severity level:

cfg := diag.Config{
	// ...
	SeverityLabels: diag.SeverityLabels{
		Error:   "erro",
		Warning: "aviso",
	},
}

DetailPad

Controls the number of spaces used to indent .Detail() text (default 2):

cfg := diag.Config{
	// ...
	DetailPad: 4,
}

API

Diagnostics

  • NewError(msg) / NewWarning(msg) creates a new diagnostic
  • .Code(code) attaches an error code shown in the header
  • .Detail(paragraphs...) sets the detail body rendered as indented prose below the header
  • .Snippet(s) attaches a source code snippet
  • .Help(text) appends a help note
  • .Note(text) appends an informational note

Regardless of the order methods are chained, the output always renders in a fixed sequence: header, detail, snippets, then hints (help and note).

Snippets

  • NewSnippet(src) creates a snippet from a byte slice
  • .File(name) sets the file name shown above the snippet
  • .From(line, col) / .To(line, col) sets the highlighted range
  • .Message(text) sets the label shown under the highlight
  • .Pad(n) sets how many context lines to show around the highlight (default 2)
  • .TabWidth(n) sets the tab width used for alignment (default 4)

Stability

diag is pre-1.0. The API is functional and tested, but minor versions may introduce breaking changes as the library grows. If you depend on it, pin to a specific version and review the changelog before upgrading.

Roadmap

These are the features planned before a stable 1.0 release:

  • Syntax highlighting for snippet blocks, likely powered by chroma, with configurable language detection and theme support
  • Text wrapping for detail and hint content, using terminal width detection with a configurable fallback column limit
  • List blocks for attaching structured bullet-point content to a diagnostic
  • Table blocks for displaying tabular data inline in the output

Have a feature in mind that isn't listed here? Open a feature request.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Characters

type Characters struct {
	Top      string
	Mid      string
	Bot      string
	Dash     string
	Dot      string
	HintHelp string
	HintNote string
}

func DefaultCharacters

func DefaultCharacters() Characters

type Config

type Config struct {
	Profile        colorprofile.Profile
	Theme          Theme
	Characters     Characters
	Prefixes       Prefixes
	SeverityLabels SeverityLabels
	DetailPad      int
}

func DefaultConfig

func DefaultConfig() Config

type Diagnostic

type Diagnostic struct {
	// contains filtered or unexported fields
}

func NewError

func NewError(msg string) Diagnostic

func NewWarning

func NewWarning(msg string) Diagnostic

func (Diagnostic) Code

func (d Diagnostic) Code(code string) Diagnostic

func (Diagnostic) Detail added in v0.2.0

func (d Diagnostic) Detail(paragraphs ...string) Diagnostic

func (Diagnostic) Help

func (d Diagnostic) Help(content string) Diagnostic

func (Diagnostic) Note

func (d Diagnostic) Note(content string) Diagnostic

func (Diagnostic) Snippet

func (d Diagnostic) Snippet(s Snippet) Diagnostic

type Prefixes

type Prefixes struct {
	Help string
	Note string
}

func DefaultPrefixes

func DefaultPrefixes() Prefixes

type Printer

type Printer struct {
	// contains filtered or unexported fields
}

func NewPrinter

func NewPrinter(w io.Writer, c Config) *Printer

func (*Printer) Print

func (p *Printer) Print(diags ...Diagnostic) error

type Severity

type Severity int
const (
	SeverityError Severity = iota
	SeverityWarning
)

type SeverityLabels

type SeverityLabels struct {
	Error   string
	Warning string
}

func DefaultSeverityLabels

func DefaultSeverityLabels() SeverityLabels

type Snippet

type Snippet struct {
	// contains filtered or unexported fields
}

func NewSnippet

func NewSnippet(content []byte) Snippet

func (Snippet) File

func (s Snippet) File(name string) Snippet

func (Snippet) From

func (s Snippet) From(line, col int) Snippet

func (Snippet) Message

func (s Snippet) Message(msg string) Snippet

func (Snippet) Pad

func (s Snippet) Pad(lines int) Snippet

func (Snippet) TabWidth

func (s Snippet) TabWidth(width int) Snippet

func (Snippet) To

func (s Snippet) To(line, col int) Snippet

type Theme

type Theme struct {
	Error   lipgloss.Style
	Warning lipgloss.Style
	Message lipgloss.Style
	Detail  lipgloss.Style
	Help    lipgloss.Style
	Note    lipgloss.Style
	Muted   lipgloss.Style
}

func DefaultTheme

func DefaultTheme() Theme

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL