Skip to content

Commit

Permalink
fix an edge case when reduced range may no longer contain cursor
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszsamson committed Feb 7, 2024
1 parent f70c9cd commit 554d7b9
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,9 @@ defmodule ElixirLS.LanguageServer.Providers.SelectionRanges do
{_, {start_line, start_character, _}, _} = previous_token
{_, {end_line, end_character, _}, _} = token

if (start_line < line or (start_line == line and start_character <= character)) and
(end_line > line or (end_line == line and end_character >= character)) do
range_between_stop_tokens = range(start_line, start_character, end_line, end_character)

if in?(range_between_stop_tokens, {line, character}) do
# dbg({previous_token, after_previous, before_stop, token})
{end_line, end_character} =
case before_stop do
Expand Down Expand Up @@ -225,15 +226,17 @@ defmodule ElixirLS.LanguageServer.Providers.SelectionRanges do
{start_line, start_character}
end

# TODO
{:halt,
{token_tuple,
[
intersection(
range(start_line, start_character, end_line, end_character),
inner_range
)
]}}
trimmed_range =
intersection(
range(start_line, start_character, end_line, end_character),
inner_range
)

if in?(trimmed_range, {line, character}) do
{:halt, {token_tuple, [trimmed_range]}}
else
{:halt, {token_tuple, []}}
end
else
{:cont, {token_tuple, []}}
end
Expand Down
5 changes: 5 additions & 0 deletions apps/language_server/lib/language_server/range_utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ defmodule ElixirLS.LanguageServer.RangeUtils do
range(0, 0, Enum.count(lines) - 1, utf8_size)
end

def in?(range(start_line, start_character, end_line, end_character), {line, character}) do
(start_line < line or (start_line == line and start_character <= character)) and
(end_line > line or (end_line == line and end_character >= character))
end

def valid?(range(start_line, start_character, end_line, end_character))
when is_integer(start_line) and is_integer(end_line) and is_integer(start_character) and
is_integer(end_character) do
Expand Down
64 changes: 64 additions & 0 deletions apps/language_server/test/providers/selection_ranges_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -996,4 +996,68 @@ defmodule ElixirLS.LanguageServer.Providers.SelectionRangesTest do
assert_range(ranges, range(0, 6, 2, 6))
end
end

describe "map update" do
test "left side of |" do
text = """
%{asd | a: 1, b: x}
"""

ranges = get_ranges(text, 0, 3)

# full range
assert_range(ranges, range(0, 0, 1, 0))
# full map
assert_range(ranges, range(0, 0, 0, 19))
# asd
assert_range(ranges, range(0, 2, 0, 5))
end

test "right side of |" do
text = """
%{asd | a: 1, b: x}
"""

ranges = get_ranges(text, 0, 9)

# full range
assert_range(ranges, range(0, 0, 1, 0))
# full map
assert_range(ranges, range(0, 0, 0, 19))
# full keyword
assert_range(ranges, range(0, 8, 0, 18))
# a: 1
assert_range(ranges, range(0, 8, 0, 12))
end

test "left side of | near" do
text = """
%{state | 1 => 1, counter: counter + to_dispatch, demand: demand - to_dispatch}
"""

ranges = get_ranges(text, 0, 8)

# full range
assert_range(ranges, range(0, 0, 1, 0))
# full map
assert_range(ranges, range(0, 0, 0, 79))
# |
assert_range(ranges, range(0, 8, 0, 9))
end

test "right side of | near" do
text = """
%{state | 1 => 1, counter: counter + to_dispatch, demand: demand - to_dispatch}
"""

ranges = get_ranges(text, 0, 9)

# full range
assert_range(ranges, range(0, 0, 1, 0))
# full map
assert_range(ranges, range(0, 0, 0, 79))
# |
assert_range(ranges, range(0, 8, 0, 9))
end
end
end

0 comments on commit 554d7b9

Please sign in to comment.