-
-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Always treat ranges as exclusive in Range.contains?/2
#768
base: main
Are you sure you want to change the base?
Conversation
c54bb63
to
89216a0
Compare
No, this is incorrect, we're using the LSP definition of cursors, namely they sit in between characters, so the code above is more accurately represented like this: The cursor is at
The cursor is sitting between the iex(1)> 1 in 1..10
true
iex(2)> 10 in 1..10
true |
Sure, I'm with you on that, but for the sake of comparing positions and ranges, I believe we still need to be exclusive. The way to select a whole line, for instance, is using the range Your point about what should trigger when you use find-refs etc. is a good one, but I believe it needs to be solved in a different way (e.g. by seeking backwards to the first non-whitespace character prior to resolving an entity "under cursor"). Elixir ranges ( |
LSP Spec supports ranges exclusive of end position: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#range |
That's a good point, but selecting lines like this is more about creating edits and not really about cursor positions. I worry that if we make ranges exclusive, we'll have to continuously adjust cursor positions whenever we're dealing with a cusor. However, when dealing with lines, we haven't yet had to adjust anything, even if, as you note, that the space between the first character on a line isn't counted as being inside the range. |
I'm not so sure; if Ultimately, I'm open to being convinced that ranges should be either end-inclusive or end-exclusive, but I strongly believe they should be one or the other (and I lean heavily toward exclusive, which is consistent with the LSP spec). Right now, they're not: single-line ranges are treated as end-inclusive, multi-line are treated as end-exclusive. I'm not sure this discrepancy is defensible. |
Agreed on the last part. Less so on the first. Let me look |
89216a0
to
9ae7a75
Compare
9ae7a75
to
2a641d0
Compare
NB: Re-opening #763 from a branch on this repo instead of from zachallaun/lexical.
Range.contains?/2
was treating the end-position of ranges as inclusive for single-line ranges, but exclusive for multi-line ranges. Our ranges should always be exclusive of the end character, however, so this was a bug. There were two other bugs/compensations that were counteracting it (at least in some cases), however:There were a lot of tests with cursor positions like this:
However, this cursor is actually "pointing" to the space after
foo
, not to the last character offoo
:Fixing
Range.contains?/2
caused all of the tests with those kinds of cursor positions to break, but I believe those tests were incorrect in the first place. I changed those cursor positions to point to the first character of the entity instead (|foo
).When detecting in strings, a number of
fetch_range
calls used a-1
end offset. This counteracted the inclusiveness of the end character inRange.contains?
, but once that was fixed, string ranges became incorrect (short one character).