Copyright | (c) 2020- comp |
---|---|
License | MIT |
Maintainer | onecomputer00@gmail.com |
Stability | stable |
Portability | portable |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
This module is for creating pretty error messages. We assume very little about the format you want to use, so much of this module is to allow you to customize your error messages.
To get started, see the documentation for prettyErrors
. When using this module, we recommend you turn on the
OverloadedStrings
extension and import Data.Text at the very least due to the use of Text
(strict).
The overall workflow to use the printer is to convert your error type to Errata
, which entails filling in messages
and Block
s. You can create Errata
and Block
from their constructors, or use the convenience functions for
common usecases, like errataSimple
and blockSimple
.
For premade styles for blocks and pointers, take a look at Errata.Styles.
For easier reading, we define:
type Line = Int type Column = Int type Header = Text type Body = Text type Label = Text
Synopsis
- data Errata = Errata {
- errataHeader :: Maybe Header
- errataBlocks :: [Block]
- errataBody :: Maybe Body
- errataSimple :: Maybe Header -> Block -> Maybe Body -> Errata
- data Block = Block {
- blockStyle :: Style
- blockLocation :: (FilePath, Line, Column)
- blockHeader :: Maybe Header
- blockPointers :: [Pointer]
- blockBody :: Maybe Body
- blockSimple :: Style -> PointerStyle -> FilePath -> Maybe Header -> (Line, Column, Column, Maybe Label) -> Maybe Body -> Block
- blockSimple' :: Style -> PointerStyle -> FilePath -> Maybe Header -> (Line, Column, Maybe Label) -> Maybe Body -> Block
- blockConnected :: Style -> PointerStyle -> FilePath -> Maybe Header -> (Line, Column, Column, Maybe Label) -> (Line, Column, Column, Maybe Label) -> Maybe Body -> Block
- blockConnected' :: Style -> PointerStyle -> FilePath -> Maybe Header -> (Line, Column, Maybe Label) -> (Line, Column, Maybe Label) -> Maybe Body -> Block
- blockMerged :: Style -> PointerStyle -> FilePath -> Maybe Header -> (Line, Column, Column, Maybe Label) -> (Line, Column, Column, Maybe Label) -> Maybe Label -> Maybe Body -> Block
- blockMerged' :: Style -> PointerStyle -> FilePath -> Maybe Header -> (Line, Column, Maybe Label) -> (Line, Column, Maybe Label) -> Maybe Label -> Maybe Body -> Block
- data Pointer = Pointer {}
- data Style = Style {
- styleLocation :: (FilePath, Line, Column) -> Text
- styleNumber :: Line -> Text
- styleLine :: [(PointerStyle, (Column, Column))] -> Text -> Text
- styleEllipsis :: Text
- styleLinePrefix :: Text
- styleVertical :: Text
- styleHorizontal :: Text
- styleDownRight :: Text
- styleUpRight :: Text
- styleUpDownRight :: Text
- styleTabWidth :: Int
- styleExtraLinesAfter :: Int
- styleExtraLinesBefore :: Int
- stylePaddingTop :: Bool
- stylePaddingBottom :: Bool
- styleEnableDecorations :: Bool
- styleEnableLinePrefix :: Bool
- data PointerStyle = PointerStyle {
- styleHighlight :: Text -> Text
- styleUnderline :: Text
- styleHook :: Text
- styleConnector :: Text
- styleEnableHook :: Bool
- prettyErrors :: Source source => source -> [Errata] -> Text
Error format data
A collection of information for pretty printing an error.
Errata | |
|
Creates a simple error that has a single block, with an optional header or body.
Blocks and pointers
Information about a block in the source code, such as pointers and messages.
Each block has a style associated with it.
Block | |
|
:: Style | The style of the block. |
-> PointerStyle | The style of the pointer. |
-> FilePath | The filepath. |
-> Maybe Header | The header message. |
-> (Line, Column, Column, Maybe Label) | The line number and column span, starting at 1, and a label. |
-> Maybe Body | The body message. |
-> Block |
A simple block that points to only one line and optionally has a label, header, or body message.
:: Style | The style of the block. |
-> PointerStyle | The style of the pointer. |
-> FilePath | The filepath. |
-> Maybe Header | The header message. |
-> (Line, Column, Maybe Label) | The line number and column, starting at 1, and a label. |
-> Maybe Body | The body message. |
-> Block |
A variant of blockSimple
that only points at one column.
:: Style | The style of the block. |
-> PointerStyle | The style of the pointer. |
-> FilePath | The filepath. |
-> Maybe Header | The header message. |
-> (Line, Column, Column, Maybe Label) | The first line number and column span, starting at 1, and a label. |
-> (Line, Column, Column, Maybe Label) | The second line number and column span, starting at 1, and a label. |
-> Maybe Body | The body message. |
-> Block |
A block that points to two parts of the source that are visually connected together.
:: Style | The style of the block. |
-> PointerStyle | The style of the pointer. |
-> FilePath | The filepath. |
-> Maybe Header | The header message. |
-> (Line, Column, Maybe Label) | The first line number and column, starting at 1, and a label. |
-> (Line, Column, Maybe Label) | The second line number and column, starting at 1, and a label. |
-> Maybe Body | The body message. |
-> Block |
A variant of blockConnected
where the pointers point at only one column.
:: Style | The style of the block. |
-> PointerStyle | The style of the pointer. |
-> FilePath | The filepath. |
-> Maybe Header | The header message. |
-> (Line, Column, Column, Maybe Label) | The first line number and column span, starting at 1, and a label. |
-> (Line, Column, Column, Maybe Label) | The second line number and column span, starting at 1, and a label. |
-> Maybe Label | The label for when the two pointers are merged into one. |
-> Maybe Body | The body message. |
-> Block |
A block that points to two parts of the source that are visually connected together.
If the two parts of the source happen to be on the same line, the pointers are merged into one.
:: Style | The style of the block. |
-> PointerStyle | The style of the pointer. |
-> FilePath | The filepath. |
-> Maybe Header | The header message. |
-> (Line, Column, Maybe Label) | The first line number and column, starting at 1, and a label. |
-> (Line, Column, Maybe Label) | The second line number and column, starting at 1, and a label. |
-> Maybe Label | The label for when the two pointers are merged into one. |
-> Maybe Body | The body message. |
-> Block |
A variant of blockMerged
where the pointers point at only one column.
A pointer is the span of the source code at a line, from one column to another. Each of the positions start at 1.
A pointer may also have a label that will display inline.
A pointer may also be connected to all the other pointers within the same block.
Pointer | |
|
Styling options
Stylization options for a block, e.g. characters to use.
Style | |
|
data PointerStyle Source #
Stylization options for an individual pointer, e.g. characters to use.
PointerStyle | |
|
Instances
Show PointerStyle Source # | |
Defined in Errata.Types showsPrec :: Int -> PointerStyle -> ShowS # show :: PointerStyle -> String # showList :: [PointerStyle] -> ShowS # |
Pretty printer
prettyErrors :: Source source => source -> [Errata] -> Text Source #
Pretty prints errors. The original source is required. Returns Text
(lazy). If the list is empty,
an empty string is returned.
Suppose we had an error of this type:
data ParseError = ParseError { peFile :: FilePath , peLine :: Int , peCol :: Int , peUnexpected :: T.Text , peExpected :: [T.Text] }
Then we can create a simple pretty printer like so:
import qualified Data.Text as T import qualified Data.Text.Lazy.IO as TL import Errata toErrata :: ParseError ->Errata
toErrata (ParseError fp l c unexpected expected) =errataSimple
(Just "an error occured!") (blockSimple
basicStyle
basicPointer
fp (Just "error: invalid syntax") (l, c, c + T.length unexpected, Just "this one") (Just $ "unexpected " <> unexpected <> "\nexpected " <> T.intercalate ", " expected)) Nothing printErrors :: T.Text -> [ParseError] -> IO () printErrors source es = TL.putStrLn $prettyErrors
source (map toErrata es)
Note that in the above example, we have OverloadedStrings
enabled to reduce uses of pack
.
An example error message from this might be:
an error occured! --> ./comma.json:2:18 error: invalid syntax | 2 | "bad": [1, 2,] | ^ this one unexpected ] expected null, true, false, ", -, digit, [, {