Always treat ranges as exclusive in Range.contains?/2#768
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?/2was 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?/2caused 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_rangecalls used a-1end offset. This counteracted the inclusiveness of the end character inRange.contains?, but once that was fixed, string ranges became incorrect (short one character).