Skip to content

Commit d59b939

Browse files
committed
When possible return non empty ranges and selection rages in documentSymbol provider
Fixes #700
1 parent 60e2df2 commit d59b939

File tree

2 files changed

+350
-921
lines changed

2 files changed

+350
-921
lines changed

apps/language_server/lib/language_server/providers/document_symbols.ex

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,13 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
8585
end
8686

8787
[module_expression, [do: module_body]] ->
88-
module_name_location = case module_expression do
89-
{_, location, _} -> location
90-
_ -> nil
91-
end
88+
module_name_location =
89+
case module_expression do
90+
{_, location, _} -> location
91+
_ -> nil
92+
end
93+
94+
# TODO extract module name location from Code.Fragment.surround_context?
9295
{extract_module_name(module_expression), module_name_location, module_body}
9396
end
9497

@@ -156,20 +159,23 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
156159
defp extract_symbol(_, {:@, _, [{kind, _, _}]}) when kind in @supplementing_attributes, do: nil
157160

158161
# Types
159-
defp extract_symbol(_current_module, {:@, location, [{type_kind, type_head_location, type_expression}]})
162+
defp extract_symbol(_current_module, {:@, location, [{type_kind, _, type_expression}]})
160163
when type_kind in [:type, :typep, :opaque, :callback, :macrocallback] do
161-
type_name =
164+
{type_name, type_head_location} =
162165
case type_expression do
163-
[{:"::", _, [{_, _, _} = type_head | _]}] ->
164-
Macro.to_string(type_head)
166+
[{:"::", _, [{_, type_head_location, _} = type_head | _]}] ->
167+
{Macro.to_string(type_head), type_head_location}
165168

166-
[{:when, _, [{:"::", _, [{_, _, _} = type_head, _]}, _]}] ->
167-
Macro.to_string(type_head)
169+
[{:when, _, [{:"::", _, [{_, type_head_location, _} = type_head, _]}, _]}] ->
170+
{Macro.to_string(type_head), type_head_location}
168171
end
172+
173+
type_name =
174+
type_name
169175
|> String.replace("\n", "")
170176

171177
type = if type_kind in [:type, :typep, :opaque], do: :class, else: :event
172-
178+
# TODO no closing metdata in type expressions
173179
%Info{
174180
type: type,
175181
name: "@#{type_kind} #{type_name}",
@@ -224,7 +230,8 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
224230

225231
defp extract_symbol(
226232
_current_module,
227-
{{:., _, [{:__aliases__, alias_location, [:Record]}, :defrecord]}, location, [record_name, properties]}
233+
{{:., _, [{:__aliases__, alias_location, [:Record]}, :defrecord]}, location,
234+
[record_name, properties]}
228235
) do
229236
name = Macro.to_string(record_name) |> String.replace("\n", "")
230237

@@ -293,8 +300,10 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
293300
keys =
294301
case config_entry do
295302
list when is_list(list) ->
296-
string_list = list
297-
|> Enum.map_join(", ", fn {key, _} -> Macro.to_string(key) end)
303+
string_list =
304+
list
305+
|> Enum.map_join(", ", fn {key, _} -> Macro.to_string(key) end)
306+
298307
"[#{string_list}]"
299308

300309
key ->
@@ -362,17 +371,27 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
362371
{start_line, start_character} =
363372
SourceFile.elixir_position_to_lsp(text, {location[:line], location[:column]})
364373

365-
{end_line, end_character} = cond do
366-
end_location = location[:end_of_expression] ->
367-
SourceFile.elixir_position_to_lsp(text, {end_location[:line], end_location[:column]})
368-
end_location = location[:end] ->
369-
SourceFile.elixir_position_to_lsp(text, {end_location[:line], end_location[:column] + 3})
370-
end_location = location[:closing] ->
371-
# all closing tags we expect hera are 1 char width
372-
SourceFile.elixir_position_to_lsp(text, {end_location[:line], end_location[:column] + 1})
373-
true ->
374-
{start_line, start_character}
375-
end
374+
{end_line, end_character} =
375+
cond do
376+
end_location = location[:end_of_expression] ->
377+
SourceFile.elixir_position_to_lsp(text, {end_location[:line], end_location[:column]})
378+
379+
end_location = location[:end] ->
380+
SourceFile.elixir_position_to_lsp(
381+
text,
382+
{end_location[:line], end_location[:column] + 3}
383+
)
384+
385+
end_location = location[:closing] ->
386+
# all closing tags we expect hera are 1 char width
387+
SourceFile.elixir_position_to_lsp(
388+
text,
389+
{end_location[:line], end_location[:column] + 1}
390+
)
391+
392+
true ->
393+
{start_line, start_character}
394+
end
376395

377396
Protocol.range(start_line, start_character, end_line, end_character)
378397
end

0 commit comments

Comments
 (0)