Skip to content

Commit 4cfc7f5

Browse files
authored
Selection ranges porvider (#1060)
* selection ranges porvider * handle structs add range operation unit tests * , and case * wip * wip * more cases covered * improve compatibility * add comments on workaround * resolve todo * move function * increase compatibility * handle one more case * improve compatibility * increase compatibility * do not run failing tests on old elixir versions * fix an edge case when reduced range may no longer contain cursor * use function * don't run on < 1.14 * resolve some todos * handle access * address todos * add test * don't run test on 1.12 * add assert * add comments * remove IO.inspect
1 parent 1ab3110 commit 4cfc7f5

File tree

14 files changed

+3294
-16
lines changed

14 files changed

+3294
-16
lines changed

apps/language_server/lib/language_server/ast_utils.ex

Lines changed: 409 additions & 0 deletions
Large diffs are not rendered by default.

apps/language_server/lib/language_server/protocol.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,15 @@ defmodule ElixirLS.LanguageServer.Protocol do
181181
end
182182
end
183183

184+
defmacro selection_range_req(id, uri, positions) do
185+
quote do
186+
request(unquote(id), "textDocument/selectionRange", %{
187+
"textDocument" => %{"uri" => unquote(uri)},
188+
"positions" => unquote(positions)
189+
})
190+
end
191+
end
192+
184193
defmacro execute_command_req(id, command, arguments) do
185194
quote do
186195
request(unquote(id), "workspace/executeCommand", %{

apps/language_server/lib/language_server/providers/folding_range/comment_block.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.CommentBlock do
3838
ranges =
3939
lines
4040
|> group_comments()
41+
|> Enum.filter(fn group -> length(group) > 1 end)
4142
|> Enum.map(&convert_comment_group_to_range/1)
4243

4344
{:ok, ranges}
4445
end
4546

4647
@spec group_comments([Line.t()]) :: [[{Line.cell(), String.t()}]]
47-
defp group_comments(lines) do
48+
def group_comments(lines) do
4849
lines
4950
|> Enum.reduce([[]], fn
5051
{_, cell, "#"}, [[{_, "#"} | _] = head | tail] ->
@@ -59,7 +60,6 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.CommentBlock do
5960
_, acc ->
6061
acc
6162
end)
62-
|> Enum.filter(fn group -> length(group) > 1 end)
6363
end
6464

6565
@spec convert_comment_group_to_range([[{Line.cell(), String.t()}]]) :: FoldingRange.t()

apps/language_server/lib/language_server/providers/folding_range/indentation.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.Indentation do
5353
{:ok, ranges}
5454
end
5555

56-
defp extract_cell({_line, cell, _first}), do: cell
56+
def extract_cell({_line, cell, _first}), do: cell
5757

5858
@doc """
5959
Pairs cells into {start, end} tuples of regions

apps/language_server/lib/language_server/providers/folding_range/special_token.ex

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,33 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.SpecialToken do
5656
end
5757

5858
@spec group_tokens([Token.t()]) :: [[Token.t()]]
59-
defp group_tokens(tokens) do
59+
def group_tokens(tokens) do
6060
do_group_tokens(tokens, [])
6161
end
6262

6363
defp do_group_tokens([], acc), do: acc
6464

65-
# Don't create folding ranges for docs
66-
defp do_group_tokens([{:identifier, _, doc_identifier}, {false, _, _} | rest], acc)
65+
# Don't create folding ranges for @doc false
66+
defp do_group_tokens(
67+
[{:at_op, _, _}, {:identifier, _, doc_identifier}, {false, _, _} | rest],
68+
acc
69+
)
6770
when doc_identifier in @docs do
6871
do_group_tokens(rest, acc)
6972
end
7073

7174
# Start a folding range for `@doc` and `@moduledoc`
72-
defp do_group_tokens([{:identifier, _, doc_identifier} = token | rest], acc)
75+
defp do_group_tokens(
76+
[{:at_op, _, _} = at_op, {:identifier, _, doc_identifier} = token | rest],
77+
acc
78+
)
7379
when doc_identifier in @docs do
74-
acc = [[token] | acc]
80+
acc = [[token, at_op] | acc]
7581
do_group_tokens(rest, acc)
7682
end
7783

7884
# Amend the folding range
79-
defp do_group_tokens([{k, _, _} = token | rest], [[{:identifier, _, _}] = head | tail])
85+
defp do_group_tokens([{k, _, _} = token | rest], [[{:identifier, _, _} | _] = head | tail])
8086
when k in @kinds do
8187
acc = [[token | head] | tail]
8288
do_group_tokens(rest, acc)
@@ -118,7 +124,7 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.SpecialToken do
118124
end
119125

120126
defp classify_group({kind, {start_line, _, _}, _}, {_, {end_line, _, _}, _}) do
121-
kind = if kind == :identifier, do: :comment, else: :region
127+
kind = if kind == :at_op, do: :comment, else: :region
122128
{start_line, end_line, kind}
123129
end
124130
end

apps/language_server/lib/language_server/providers/folding_range/token_pairs.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.TokenPair do
5858
end
5959

6060
@spec pair_tokens([Token.t()]) :: [{Token.t(), Token.t()}]
61-
defp pair_tokens(tokens) do
61+
def pair_tokens(tokens) do
6262
do_pair_tokens(tokens, [], [])
6363
end
6464

@@ -82,8 +82,8 @@ defmodule ElixirLS.LanguageServer.Providers.FoldingRange.TokenPair do
8282
pairs
8383
) do
8484
head_matches_any? = @token_pairs |> Map.has_key?(head_kind)
85-
# Map.get/2 will always succeed because we only push matches to the stack.
86-
head_matches_top? = @token_pairs |> Map.get(top_kind) |> Enum.member?(head_kind)
85+
# Map.fetch!/2 will always succeed because we only push matches to the stack.
86+
head_matches_top? = @token_pairs |> Map.fetch!(top_kind) |> Enum.member?(head_kind)
8787

8888
{new_stack, new_pairs} =
8989
case {head_matches_any?, head_matches_top?} do

0 commit comments

Comments
 (0)