## Summary
This PR remaps ranges in Jupyter notebooks from simple `row:column`
indices in the concatenated source code to `cell:row:col` to match
Ruff's output. This is probably not a likely change to land upstream in
`annotate-snippets`, but I didn't see a good way around it.
The remapping logic is taken nearly verbatim from here:
cd6bf1457d/crates/ruff_linter/src/message/text.rs (L212-L222)
## Test Plan
New `full` rendering test for a notebook
I was mainly focused on Ruff, but in local tests this also works for ty:
```
error[invalid-assignment]: Object of type `Literal[1]` is not assignable to `str`
--> Untitled.ipynb:cell 1:3:1
|
1 | import math
2 |
3 | x: str = 1
| ^
|
info: rule `invalid-assignment` is enabled by default
error[invalid-assignment]: Object of type `Literal[1]` is not assignable to `str`
--> Untitled.ipynb:cell 2:3:1
|
1 | import math
2 |
3 | x: str = 1
| ^
|
info: rule `invalid-assignment` is enabled by default
```
This isn't a duplicate diagnostic, just an unimaginative example:
```py
# cell 1
import math
x: str = 1
# cell 2
import math
x: str = 1
```
This is a fork of the annotate-snippets crate. The principle motivation for
this fork, at the time of writing, is issue #167. Specifically, we wanted to
upgrade our version of annotate-snippets, but do so without changing our
diagnostic message format.
This copy of annotate-snippets is basically identical to upstream, but with
an extra Level::None variant that permits skipping over a new non-optional
header emitted by annotate-snippets.
More generally, it seems plausible that we may want to tweak other aspects of the output format in the future, so it might make sense to stick with our own copy so that we can be masters of our own destiny.