Giter Site home page Giter Site logo

brendanzab / codespan Goto Github PK

View Code? Open in Web Editor NEW
1.0K 14.0 55.0 960 KB

Beautiful diagnostic reporting for text-based programming languages.

License: Apache License 2.0

Rust 100.00%
error-reporting programming-languages source-code rust diagnostics terminal

codespan's Introduction

codespan-reporting

Continuous integration Crates.io Docs.rs Matrix

Beautiful diagnostic reporting for text-based programming languages.

Example preview

Languages like Rust and Elm already support beautiful error reporting output, but it can take a significant amount work to implement this for new programming languages! The codespan-reporting crate aims to make beautiful error diagnostics easy and relatively painless for everyone!

We're still working on improving the crate to help it support broader use cases, and improving the quality of the diagnostic rendering, so stay tuned for updates and please give us feedback if you have it. Contributions are also very welcome!

Example

use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};

// `files::SimpleFile` and `files::SimpleFiles` help you get up and running with
// `codespan-reporting` quickly! More complicated use cases can be supported
// by creating custom implementations of the `files::Files` trait.

let mut files = SimpleFiles::new();

let file_id = files.add(
    "FizzBuzz.fun",
    unindent::unindent(
        r#"
            module FizzBuzz where

            fizz₁ : Nat → String
            fizz₁ num = case (mod num 5) (mod num 3) of
                0 0 => "FizzBuzz"
                0 _ => "Fizz"
                _ 0 => "Buzz"
                _ _ => num

            fizz₂ : Nat → String
            fizz₂ num =
                case (mod num 5) (mod num 3) of
                    0 0 => "FizzBuzz"
                    0 _ => "Fizz"
                    _ 0 => "Buzz"
                    _ _ => num
        "#,
    ),
);

// We normally recommend creating a custom diagnostic data type for your
// application, and then converting that to `codespan-reporting`'s diagnostic
// type, but for the sake of this example we construct it directly.

let diagnostic = Diagnostic::error()
    .with_message("`case` clauses have incompatible types")
    .with_code("E0308")
    .with_labels(vec![
        Label::primary(file_id, 328..331).with_message("expected `String`, found `Nat`"),
        Label::secondary(file_id, 211..331).with_message("`case` clauses have incompatible types"),
        Label::secondary(file_id, 258..268).with_message("this is found to be of type `String`"),
        Label::secondary(file_id, 284..290).with_message("this is found to be of type `String`"),
        Label::secondary(file_id, 306..312).with_message("this is found to be of type `String`"),
        Label::secondary(file_id, 186..192).with_message("expected type `String` found here"),
    ])
    .with_notes(vec![unindent::unindent(
        "
            expected type `String`
                found type `Nat`
        ",
    )]);

// We now set up the writer and configuration, and then finally render the
// diagnostic to standard error.

let writer = StandardStream::stderr(ColorChoice::Always);
let config = codespan_reporting::term::Config::default();

term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;

Running the CLI example

To get an idea of what the colored CLI output looks like, clone the repository and run the following shell command:

cargo run --example term

More examples of using codespan-reporting can be found in the examples directory.

Projects using codespan-reporting

codespan-reporting is currently used in the following projects:

Alternatives to codespan-reporting

There are a number of alternatives to codespan-reporting, including:

These are all ultimately inspired by rustc's excellent error reporting infrastructure.

Contributing

A guide to contributing to codespan-reporting can be found here.

Code of Conduct

Please note that this project is released with a Code of Conduct. By participating in this project you agree to abide by its terms.

codespan's People

Contributors

andrewhickman avatar brendanzab avatar declanvk avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dtolnay avatar ebkalderon avatar eduardosm avatar elkowar avatar etaoins avatar garyttierney avatar johann150 avatar jyn514 avatar kvark avatar laegluin avatar lpil avatar marwes avatar mbartlett21 avatar memoryruins avatar michael-f-bryan avatar oberien avatar ooboomberoo avatar ratmice avatar rdambrosio016 avatar sagacity avatar sematre avatar shika-blyat avatar stupremee avatar waywardmonkeys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

codespan's Issues

Does not span multilines?

I have a codespan that starts in one line and ends in the next. However, it seems that the underlying termcolor library is misbehaving.

Expand documentation

I want to use this crate in my project, but I don't know how to use it 🤔

Given a file or string of source code, and a start and end location of a token, how do I produce an error message pointing to the location?

If someone helps explain, I can contribute with writing some documentation.

Support for integrating with in-browser editors

It would be really neat to be easily able to integrate diagnostic reporting with in-browser editors - either when your language is compiled to webasm, or when communicating over HTTP. Perhaps we could focus on one in the short term. There are a number out there, for example:

Would also be nice to have a tutorial and/or example showing how this could be done.

Incorrect number alignment in rendered diagnostics

There appears to be an issue when rendering diagnostics' line numbers with codespan 0.5. The output looks something like this:

error: unterminated block comment

    ┌── stdin:8:5 ───
    │
 8 │ ╭     /*
 9 │ │     buildInputs = [
 10 │ │       (nixpkgs.rustChannelOf { channel = "stable"; }).rust
 11 │ │       # nixpkgs.darwin.apple_sdk.frameworks.Security
 12 │ │       # nixpkgs.darwin.apple_sdk.frameworks.CoreServices
 13 │ │       nixpkgs.jq
 14 │ │       nixpkgs.sqlite
 15 │ │     ];
 16 │ │   }
 17 │ │
    │ ╰^ unterminated block comment
    │

The line numbers are aligned to the left instead of the right, thereby breaking the ASCII art.

Improve error formatting for CLI applications

Currently I'm not doing much about this. Here are some options

  • We could try to follow Rust closely.
  • Get inspiration from other languages and go our own way.
  • Provide multiple error formatting styles (could help us support other backends, like the Language Server Protocol).

I'd also like to be able to support domain-specific errors, such as those produced by LALRPOP - at least providing an escape hatch to allow them to be easily created!

Inspiration:

Here are some examples of what the output might look like:

Reason

Source code

Reason error output

Reason warning output

Reason React error

LALRPOP

Source code

calc.lalrpop:6:5: 6:34: Ambiguous grammar detected

  The following symbols can be reduced in two ways:
    Expr "*" Expr "*" Expr

  They could be reduced like so:
    Expr "*" Expr "*" Expr
    ├─Expr──────┘        │
    └─Expr───────────────┘

  Alternatively, they could be reduced like so:
    Expr "*" Expr "*" Expr
    │        └─Expr──────┤
    └─Expr───────────────┘

  Hint: This looks like a precedence error related to `Expr`. See the LALRPOP
  manual for advice on encoding precedence.

Elm

Source code

Elm big record error

Elm error

Rust

Source code

Rust overflow error

Rust lifetime error

Group labels originating from the same file into a single snippet

As mentioned in #77, Rustc does a clever job of grouping together labels:

It would be super neat if we could do something similar!

At the moment our diagnostics are all spread out:

error[E0308]: `case` clauses have incompatible types

   ┌── FizzBuzz.fun:8:12 ───
   │
 8 │     _ _ => num
   │            ^^^ expected `String`, found `Nat`
   │
   = expected type `String`
        found type `Nat`

   ┌── FizzBuzz.fun:4:13 ───
   │
 4 │   fizz₁ num = case (mod num 5) (mod num 3) of
   │ ╭─────────────'
 5 │ │     0 0 => "FizzBuzz"
 6 │ │     0 _ => "Fizz"
 7 │ │     _ 0 => "Buzz"
 8 │ │     _ _ => num
   │ ╰──────────────' `case` clauses have incompatible types
   │

   ┌── FizzBuzz.fun:3:15 ───
   │
 3 │ fizz₁ : Nat → String
   │               ------ expected type `String` found here
   │

It would be great if we could collapse things down, for example:

error[E0308]: `case` clauses have incompatible types

   ┌── FizzBuzz.fun:8:12 ───
   │
 3 │   fizz₁ : Nat → String
   │                 ------ expected type `String` found here
 4 │   fizz₁ num = case (mod num 5) (mod num 3) of
   │ ╭─────────────'
 5 │ │     0 0 => "FizzBuzz"
 6 │ │     0 _ => "Fizz"
 7 │ │     _ 0 => "Buzz"
 8 │ │     _ _ => num
   │ │            ^^^ expected `String`, found `Nat`
   │ ╰──────────────' `case` clauses have incompatible types
   │
   = expected type `String`
        found type `Nat`

Or in the case of that rustc error:

error[E0308]: match arms have incompatible types

    ┌─ codespan/src/file.rs:102:34
    :
99  │  ╭──────── match line_index.compare(self.last_line_index()) {
100 │  │             Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
    │  │                               --------------------------------------------- this is found to be of type `std::result::Result<index::ByteIndex, file::LineIndexOutOfBoundsError>`
101 │  │             Ordering::Equal => Ok(self.source_span().end()),
    │  │                                ---------------------------- this is found to be of type `std::result::Result<index::ByteIndex, file::LineIndexOutOfBoundsError>`
102 │  │             Ordering::Greater => LineIndexOutOfBoundsError {
    │ ╭│──────────────────────────────────^
103 │ ││                 given: line_index,
104 │ ││                 max: self.last_line_index(),
105 │ ││             },
    │ ╰│─────────────^ expected enum `std::result::Result`, found struct `file::LineIndexOutOfBoundsError`
106 │  │         }
    │  ╰─────────' `match` arms have incompatible types
    :
    = note: expected type `std::result::Result<index::ByteIndex, file::LineIndexOutOfBoundsError>`
               found type `file::LineIndexOutOfBoundsError`

It might be worth studying how librustc_errors does this. There's a bunch of clever logic in emitter.rs that it might be worth understanding.

Release v0.4.0

Lots of work has been done to improve the API in the time since the last release. What do we need to do to get v0.4.0 out the door?

cc. @Marwes

Allow removal and updating of the FileMap's inside CodeMap's

For language servers the sources will be frequently modified and old sources (FileMaps) will be thrown out eventually. As CodeMap works now though, it is not possible to remove a source once it is added which means that memory use will grow for each modification to a file.

If removal of FileMaps are possible we could maybe run into fragmentation issues for Span allocation but I think that in practice this can largely be ignored (or we could use some simple memory allocator approach to remedy memory fragmentation).

Indexing with `ByteIndex`

If I'm not mistaken, ByteIndex uses 1-based indexing, but that is never mentioned in the docs. This should probably be documented, since I would have expected it to be 0-based.

I'd happily submit a PR with some changes :)

Use another identifier than 'Label'

Label is a pretty common term in programming languages, and one that I currently conflict with! Instead In need to do:

use codespan_reporting::Label as DiagnosticLabel;

Some ways to fix this could be to:

  • Use a different identifier, like Note.
  • Use a type alias instead, ie:
    type Label = (FileId, Span, String);

Thoughts?

Support for the Language Server Protocol

It would be nice to have a clean way of building language servers using codespan. I'm not sure how much of it we will be able to automate though, and how much would be up to the user to build. At least having some nice serializers for the diagnostics would be handy.

Add examples of working with other libraries

It would be nice to show how codespan can be used in conjunction with other libraries. Some ones we might want to show are:

Candidate libraries

Incremental Compilation

We get a number of requests (#172, #179) about Salsa, so we could do with a simple example showing how we recommend using it with codespan-reporting!

Parsers

Many people get started building languages using parser generators, so showing them how to get codespan hooked up to these would be very useful!

Pretty printing

It would be nice to have an example of pretty printing types, with source code highlighting, and potentially nifty things like type diffs.

Custom databases (Salsa support)

It would be nice to be able to define custom Files-style databases depending on the needs of a project.

  • People might want to use something like Salsa to manage their source files.
  • When starting off building a language, a 'SingleFile' database (that only took a single file) might be a better solution than #56.
  • Others might want to use a more compact span representation than the one used currently. For example compressing it, as is done in rustc.

The language-reporting fork defines ReportingSpan and ReportingFiles traits which might be useful for inspiration.

Wrap lines to terminal width

I'm thinking it might be useful to pass in an optional width for line wrapping in the Config struct. This would wrap lines and error messages. If we can figure out how to also include types like those from pretty, then these might be able to take advantage of this information as well.

Accessibility considerations for error reporting

Our error reporting should be accessible to people with low, to non-sighted users, and also those who are colour blind.

I think at the moment we support colour blind users reasonably well - ie. colour enhnces the experience, but is not required. It would be interesting to know how non-sighted people fare, and how our error reporting works with terminals with large text sizes.

Wondering if we should do some design documentation surrounding this? Is there any existing resources out there with regards to accessibility for error reporting?

Release new version of codespan-lsp

It appears that lsp-types has recently been bumped to version 0.63.1, making codespan-lsp 0.5.0 no longer semver-compatible with this latest version. This new release adds support for LSP 3.15, which includes a number of improvements over the previous release. It would be nice if codespan-lsp could be bumped on Crates.io to work with this new release.

Implement or derive Default for Span

Prior to the release of codespan 0.4.0, the codespan::Span type used to derive Default. I personally found this quite handy when hacking on ASTs where I did not care about the span information, and I could conveniently specify Default::default() everywhere a Span was expected without having to import it.

In particular, I also happen to find the Default implementation handy when writing macros that construct ASTs, since they eliminate the need to depend on codespan and import the type. So if a downstream crate were to import the macro, it would not require the user to depend on codespan, or for the crate author to re-export codespan::Span for the macro to use.

Are there any technical reasons to not derive Default on Span? If there aren't, it would be a nice touch in the ergonomics department.

Add an easy way to get spans from filemaps

At the moment you need to go through the CodeMap to get a new span. And example of this is here:

https://github.com/pikelet-lang/pikelet/blob/0d8eaa35a7169cf9d4466acd08cbe301b72e590e/src/syntax/parse/lexer.rs#L245-L252

This is not very discoverable, and a couple of users have been caught up on this before!

Perhaps we could have a FileMap::span_for method. Or perhaps a SpanCreator thingy that is Copy. That way folks could pass it around without having to worry about ownership.

Take T: Display instead of String for Label and Diagnostic

Currently, I'm writing code that looks like this:

     for warning in warnings {
        let label = Label::new(file, warning.location.span, warning.data.to_string());
        Diagnostic::new_warning(warning.data.to_string(), label);
        // TODO: emit warning
    }

My warnings are fairly compact error enums. If new_warning and Label::new took Display instead, they could

  • take up less space in memory, and
  • I wouldn't have to write to_string() so much

Deduplicate files

Currently, calling Files.add(name, file) twice in a row will duplicate the entire file, wasting memory. It would be nice to deduplicate by only storing the file once. This could be done by storing a HashMap<name, FileID> which returns the id if the file already exists.

This would mean that users can no longer add two different files with the same name, but I think that's fine as long as it's documented.

Getting a line slice requires two error checks

Presumably line_span always returns a valid span. However, the API requires you to check the error anyway:

    let line = file_db
        .line_span(file, start.line)
        .expect("line should be in bounds");
    println!("{}", file_db.source_slice(file, line).expect("line is still in bounds"));

I would like Files to get a new line_slice API which returns a Result<&str, LineIndexOutOfBoundsError> directly.

Allow setting custom line numbers

This is a bit of an edge case ... In C there is a #line macro that allows setting the current line number, it looks like this:

void f();
int main() {
    #line 1
    return f();
}
<stdin>:1:12: error: returning 'void' from a function with incompatible result type
      'int'

Note how the error message says the error occurs on line 1, not line 4.

Currently, it looks like the lines in a file are calculated once and can't be modified. Would it be possible to make the line numbers configurable?

This has the unfortunate complication that there's no longer a 1-1 mapping between the line numbers displayed to the user and the lines in a file: in my example above, there are 2 lines with line number 1. However, this corresponds pretty closely to the current difference between LineIndex (internal) and LineNumber (user-facing) so I don't forsee it being a giant deal.

Support collapsing multi line output

Love the library, but there's an issue when using it with long multi-line spans--it shows every line!

I believe the lines that would need to be changed are these:

for line_index in ((start.line.to_usize() + 1)..end.line.to_usize())
.map(|i| LineIndex::from(i as u32))
{

image

rustc, on the other hand, will collapse multiple line spans:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0d4c7f47b06cefb15528f7106766d5f7

image

Does codespan support this?

Release new version of codespan-lsp

Since codespan-lsp 0.4.1 still requires lsp-types 0.60.0, language servers relying on this library are currently unusable on JetBrains IDEs such as IntelliJ or WebStorm because of an issue with the document version schema, currently fixed in lsp-types 0.61.0 (gluon-lang/lsp-types#113). It appears that the lsp-types version requirement for codespan-lsp has already been bumped and merged into master in this commit, but it isn't yet available on Crates.io.

[Request] Usage Guide

A usage guide / book for codespan would go a long way, I believe.


I am using gluon and pikelet as references but am having a difficult time figuring out how to correctly use this library (lifetime/ownership issues, some specifically regarding FileMap).

The two reference projects I mentioned make use of lalrpop which may make using codespan easier but I do not want to use lalrpop so I feel like I'm stuck out at sea here.

Allow non-utf8 filenames

Filenames on Unix can be arbitrary bytes; on Windows they can be arbitrary UTF16 (and I think there's some strangeness around surrogate pairs).

error[E0277]: the trait bound `std::string::String: std::convert::From<std::path::PathBuf>` is not satisfied
   --> src/main.rs:108:27
    |
108 |     let file_id = file_db.add(opt.filename, buf);
    |                           ^^^ the trait `std::convert::From<std::path::PathBuf>` is not implemented for `std::string::String`
    |
    = help: the following implementations were found:
              <std::string::String as std::convert::From<&std::string::String>>
              <std::string::String as std::convert::From<&str>>
              <std::string::String as std::convert::From<rcc::data::LengthError>>
              <std::string::String as std::convert::From<std::borrow::Cow<'a, str>>>
              <std::string::String as std::convert::From<std::boxed::Box<str>>>
    = note: required because of the requirements on the impl of `std::convert::Into<std::string::String>` for `std::path::PathBuf`

Rename codespan-reporting

With the addition of the Files trait, codespan-reporting is now decoupled entirely from codespan. I'm wondering if we should consider renaming it? language-reporting is already taken, but maybe we could call it something else:

  • text-reporting
  • code-reporting
  • lang-reporting
  • source-reporting

Curious if anybody has any thoughts!

Improve multiline errors

As can be seen in the emitter example the error for multiline errors could be improved.

Currently we render:

   ┌── FizzBuzz.fun:4:13 ───
   │
 4 │ fizz₁ num = case (mod num 5) (mod num 3) of
 5 │     0 0 => "FizzBuzz"
 6 │     0 _ => "Fizz"
 7 │     _ 0 => "Buzz"
 8 │     _ _ => num
   │             -------------- `case` clauses have incompatible types
   │

Instead, it might be nice if we followed rustc's lead, and tried to mark around the region instead:

   ┌── FizzBuzz.fun:4:13 ───
   │
 4 │   fizz₁ num = case (mod num 5) (mod num 3) of
   │ ╭─────────────╯
 5 │ │     0 0 => "FizzBuzz"
 6 │ │     0 _ => "Fizz"
 7 │ │     _ 0 => "Buzz"
 8 │ │     _ _ => num
   │ ╰──────────────╯ `case` clauses have incompatible types
   │

Eventually we could try to combine errors like so:

error[E0308]: `case` clauses have incompatible types

   ┌── FizzBuzz.fun:8:12 ───
   │
 3 │   fizz₁ : Nat → String
   │                 ------ expected type `String` found here
 4 │   fizz₁ num = case (mod num 5) (mod num 3) of
   │ ╭─────────────╯
 5 │ │     0 0 => "FizzBuzz"
 6 │ │     0 _ => "Fizz"
 7 │ │     _ 0 => "Buzz"
 8 │ │     _ _ => num
   │ │            ^^^ expected `String`, found `Nat`
   │ ╰──────────────╯ `case` clauses have incompatible types
   │
   = expected type `String`
        found type `Nat`

Should we coordinate a migration to 'language-reporting'?

@wycats, @nikomatsakis and @jonathandturner have done some great work in building on top of our work in codespan in their branch here as part of their work on Lark. It builds on top of the work of codespan, making it more configurable through the use of traits, and less confusing by using file ids. I've been using it in https://github.com/brendanzab/rust-nbe-for-mltt and have been quite happy!

The question though is: where to from here? Should we close down this repository and direct people to @wycats' project? Or should we try to take on the changes into this repository? I'm still a bit hesitant to take on the render-tree dependency, as I don't fully understand it yet.

Thoughts?

Useful PRs that might need to be up-streamed:

  • #51: multiline error reporting
  • #53: more space in emit output

Make codespan_repoirting::emit take a multiple reference to the writer

There doesn't seem to be any reason for it to consume the writer other than to force the user to lock the output multiple times. I just can't think of any reason for the emit function to take the writer argument by value and I don't know if I can say much more about this. It should be a trivial change.

Release new version of codespan-lsp

The lsp-types crate has been recently bumped to 0.70.2, but the latest codespan-lsp 0.7.0 is apparently still stuck on version 0.68. This means that users of codespan-lsp do not have access to the latest features of the specification and LSP library authors mindful of codespan-lsp cannot upgrade their dependency on lsp-types to 0.70.X without breaking downstream code that relies both crates.

Because of this, it would be great if there could be a new release of codespan-lsp 0.8.0 to Crates.io, so the two crate ecosystems do not diverge too far.

CC @brendanzab @Marwes

Deprecate the diagnostic conversion part of codespan-lsp

Having done some work with diagnostic formatting, I'm feeling more that language implementers should be creating intermediate enumerations of for their diagnostic messages, then sending those to various front-ends - be they a CLI, or a language server, etc.

This would help to make it easier to craft messages for those specific front-end, and save us the pain of trying to convert a common diagnostic format between front-ends. At the moment they don't fully match up, and this means we have to do some messy hacks in order to make it work .

Add simple diagnostic rendering mode

As part of #30 it might be nice to have a simple diagnostic rendering mode to make it easier on screen readers. This would only display a list of diagnostics, without the source snippets.

Here's an example of what it might look like:

error[E0308]: `case` clauses have incompatible types
    - FizzBuzz.fun:8:12: expected `String`, found `Nat`
        = expected type `String`
             found type `Nat`
        = FizzBuzz.fun:4:13: `case` clauses have incompatible types
        = FizzBuzz.fun:3:15: expected type `String` found here

error[E0308]: `case` clauses have incompatible types
    - FizzBuzz.fun:15:16: expected `String`, found `Nat`
        = expected type `String`
             found type `Nat`
        = FizzBuzz.fun:11:5: `case` clauses have incompatible types
        = FizzBuzz.fun:12:16: this is found to be of type `String`
        = FizzBuzz.fun:13:16: this is found to be of type `String`
        = FizzBuzz.fun:14:16: this is found to be of type `String`

Perhaps others have better ideas though?

RichDiagnostic should point to the source of the primary label

https://github.com/brendanzab/codespan/blob/master/codespan-reporting/src/term/views/source_snippet/mod.rs#L60#L66

https://github.com/brendanzab/codespan/blob/master/codespan-reporting/src/term/views/source_snippet/mod.rs#L87#L107

In SourceSnippet reporting, it tries to determine the max region of the error. Perhaps in previous versions this made sense, but in the latest version, the diagnostics are a PrimaryLabel + a list of other second labels (with notes and warnings, etc)

So it feels very peculiar to not just point to the PrimaryLabel's location in the span of the error message.

Consider this example from Rust:

error[E0308]: if and else have incompatible types
   --> path/to/my_file.rs:221:9
    |
218 | /     if (true) {
219 | |         5
    | |         - expected because of this
220 | |     } else {
221 | |         false
    | |         ^^^^^ expected integer, found bool
222 | |     };
    | |_____- if and else have incompatible types
    |

SourceSnippet would put this min/maxed box of path/to/my_file.rs:219:14 as the location, not path/to/my_file.rs:221:9 which is the location of the primary label

Make it easy to set emitter config for CLIs

It would be nice if we had a good way to set the styling for terminal CLIs in a standard way, without too much drama - either via command line flags or config files. I'm not sure what this would look like though, and I don't want to couple us to a specific command line parser or config format, but am also wary of something too astronautical.

Ultimately we should be able to set up the emitter example have its display configuration be customisable without too much trouble.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.