Skip to content

Commit 66847b5

Browse files
committed
Use detail on document symbol
Do not include def as part of symbol name as it breaks search. this behavior has been introduced in f5a627c This commit puts that info into detail
1 parent 0b9fec1 commit 66847b5

File tree

4 files changed

+194
-192
lines changed

4 files changed

+194
-192
lines changed

apps/language_server/lib/language_server/protocol/document_symbol.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ defmodule ElixirLS.LanguageServer.Protocol.DocumentSymbol do
55
For details see https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol
66
"""
77
@derive JasonV.Encoder
8-
defstruct [:name, :kind, :range, :selectionRange, :children]
8+
defstruct [:name, :detail, :kind, :range, :selectionRange, :children]
99
end

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

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
88
alias ElixirLS.LanguageServer.Providers.SymbolUtils
99
alias ElixirLS.LanguageServer.{SourceFile, Parser}
1010
require ElixirLS.LanguageServer.Protocol, as: Protocol
11+
alias ElixirSense.Core.Normalized.Module, as: NormalizedModule
1112

1213
defmodule Info do
13-
defstruct [:type, :name, :location, :children, :selection_location, :symbol]
14+
defstruct [:type, :name, :detail, :location, :children, :selection_location, :symbol]
1415
end
1516

1617
@macro_defs [:defmacro, :defmacrop, :defguard, :defguardp]
@@ -68,34 +69,34 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
6869
# Modules, protocols
6970

7071
defp extract_symbol(_module_name, {defname, location, arguments})
71-
when defname in [:defmodule, :defprotocol] do
72+
when defname in [:defmodule, :defprotocol, :defimpl_transformed] do
7273
module_info =
7374
case arguments do
7475
# Handles `defmodule do\nend` type compile errors
7576
[[do: module_body]] ->
7677
# The LSP requires us to return a non-empty name
7778
case defname do
78-
:defmodule -> {"MISSING_MODULE_NAME", nil, module_body}
79-
:defprotocol -> {"MISSING_PROTOCOL_NAME", nil, module_body}
79+
:defmodule -> {"MISSING_MODULE_NAME", nil, nil, module_body}
80+
:defprotocol -> {"MISSING_PROTOCOL_NAME", nil, nil, module_body}
8081
end
8182

8283
[module_expression, [do: module_body]] ->
83-
module_name_location =
84+
{module_name_location, symbol} =
8485
case module_expression do
85-
{_, location, _} -> location
86-
_ -> nil
86+
{_, location, _} -> {location, Macro.to_string(module_expression)}
87+
_ -> {nil, nil}
8788
end
8889

8990
# TODO extract module name location from Code.Fragment.surround_context?
9091
# TODO better selection ranges for defimpl?
91-
{extract_module_name(module_expression), module_name_location, module_body}
92+
{extract_module_name(module_expression), symbol, module_name_location, module_body}
9293

9394
_ ->
9495
nil
9596
end
9697

9798
if module_info do
98-
{module_name, module_name_location, module_body} = module_info
99+
{module_name, symbol, module_name_location, module_body} = module_info
99100

100101
mod_defns =
101102
case module_body do
@@ -114,16 +115,18 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
114115
type =
115116
case defname do
116117
:defmodule -> :module
118+
:defimpl_transformed -> :module
117119
:defprotocol -> :interface
118120
end
119121

120122
%Info{
121123
type: type,
122-
name: module_name,
124+
name: symbol || module_name,
125+
detail: if(defname == :defimpl_transformed, do: :defimpl, else: defname),
123126
location: location,
124127
selection_location: module_name_location,
125128
children: module_symbols,
126-
symbol: module_name
129+
symbol: symbol || module_name
127130
}
128131
end
129132
end
@@ -135,7 +138,7 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
135138
) do
136139
extract_symbol(
137140
module_name,
138-
{:defmodule, location,
141+
{:defimpl_transformed, location,
139142
[[protocol: protocol_expression, implementations: for_expression], [do: module_body]]}
140143
)
141144
end
@@ -155,6 +158,7 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
155158
%Info{
156159
type: :struct,
157160
name: "#{defname} #{module_name}",
161+
detail: defname,
158162
location: location,
159163
children: children
160164
}
@@ -169,45 +173,39 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
169173
not is_nil(type_expression) do
170174
type_name_location =
171175
case type_expression do
172-
[{:"::", _, [{_, type_head_location, _} = type_head | _]}] ->
173-
{Macro.to_string(type_head), type_head_location}
176+
[{:"::", _, [{name, type_head_location, args} = type_head | _]}] ->
177+
{{name, args}, type_head_location}
174178

175-
[{:when, _, [{:"::", _, [{_, type_head_location, _} = type_head, _]}, _]}] ->
176-
{Macro.to_string(type_head), type_head_location}
179+
[{:when, _, [{:"::", _, [{name, type_head_location, args} = type_head, _]}, _]}] ->
180+
{{name, args}, type_head_location}
177181

178-
[{_, type_head_location, _} = type_head | _] ->
179-
{Macro.to_string(type_head), type_head_location}
182+
[{name, type_head_location, args} = type_head | _] ->
183+
{{name, args}, type_head_location}
180184

181185
_ ->
182186
nil
183187
end
184188

185189
if type_name_location do
186-
{type_name, type_head_location} = type_name_location
187-
188-
type_name =
189-
type_name
190-
|> String.replace(~r/,*\n\s*/u, fn
191-
"," <> _ -> ", "
192-
_ -> ""
193-
end)
190+
{{name, args}, type_head_location} = type_name_location
194191

195192
type = if type_kind in [:type, :typep, :opaque], do: :class, else: :event
196193

197194
%Info{
198195
type: type,
199-
name: "@#{type_kind} #{type_name}",
196+
name: "#{name}/#{length(args || [])}",
197+
detail: "@#{type_kind}",
200198
location: location,
201199
selection_location: type_head_location,
202-
symbol: "#{type_name}",
200+
symbol: to_string(name),
203201
children: []
204202
}
205203
end
206204
end
207205

208206
# @behaviour BehaviourModule
209207
defp extract_symbol(_current_module, {:@, location, [{:behaviour, _, [behaviour_expression]}]}) do
210-
module_name = extract_module_name(behaviour_expression)
208+
module_name = Macro.to_string(behaviour_expression)
211209

212210
%Info{type: :interface, name: "@behaviour #{module_name}", location: location, children: []}
213211
end
@@ -220,10 +218,10 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
220218
# Function, macro, guard with when
221219
defp extract_symbol(
222220
_current_module,
223-
{defname, location, [{:when, _, [{_, head_location, _} = fn_head, _]} | _]}
221+
{defname, location, [{:when, _, [{name, head_location, args} = fn_head, _]} | _]}
224222
)
225223
when defname in @defs do
226-
name =
224+
head =
227225
Macro.to_string(fn_head)
228226
|> String.replace(~r/,*\n\s*/u, fn
229227
"," <> _ -> ", "
@@ -232,18 +230,22 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
232230

233231
%Info{
234232
type: if(defname in @macro_defs, do: :constant, else: :function),
235-
symbol: "#{name}",
236-
name: "#{defname} #{name}",
233+
symbol: to_string(name),
234+
name: "#{to_string(name)}/#{length(args || [])}",
235+
detail: defname,
237236
location: location,
238237
selection_location: head_location,
239238
children: []
240239
}
241240
end
242241

243242
# Function, macro, delegate
244-
defp extract_symbol(_current_module, {defname, location, [{_, head_location, _} = fn_head | _]})
243+
defp extract_symbol(
244+
_current_module,
245+
{defname, location, [{name, head_location, args} = fn_head | _]}
246+
)
245247
when defname in @defs do
246-
name =
248+
head =
247249
Macro.to_string(fn_head)
248250
|> String.replace(~r/,*\n\s*/u, fn
249251
"," <> _ -> ", "
@@ -252,8 +254,9 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
252254

253255
%Info{
254256
type: if(defname in @macro_defs, do: :constant, else: :function),
255-
symbol: "#{name}",
256-
name: "#{defname} #{name}",
257+
symbol: to_string(name),
258+
name: "#{to_string(name)}/#{length(args || [])}",
259+
detail: defname,
257260
location: location,
258261
selection_location: head_location,
259262
children: []
@@ -278,7 +281,8 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
278281

279282
%Info{
280283
type: :class,
281-
name: "defrecord #{name}",
284+
name: "#{name}",
285+
detail: :defrecord,
282286
location: location |> Keyword.merge(Keyword.take(alias_location, [:line, :column])),
283287
children: children
284288
}
@@ -288,7 +292,8 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
288292
defp extract_symbol(_current_module, {:test, location, [name | _]}) do
289293
%Info{
290294
type: :function,
291-
name: "test #{Macro.to_string(name)}",
295+
name: Macro.to_string(name),
296+
detail: :test,
292297
location: location,
293298
children: []
294299
}
@@ -320,7 +325,8 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
320325

321326
%Info{
322327
type: :function,
323-
name: "describe #{Macro.to_string(name)}",
328+
name: Macro.to_string(name),
329+
detail: :describe,
324330
location: location,
325331
children: module_symbols
326332
}
@@ -374,6 +380,7 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
374380

375381
%Protocol.DocumentSymbol{
376382
name: info.name,
383+
detail: info.detail,
377384
kind: SymbolUtils.symbol_kind_to_code(info.type),
378385
range: range,
379386
selectionRange: selection_range,
@@ -481,7 +488,7 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
481488
)
482489

483490
symbol != nil ->
484-
end_char = SourceFile.elixir_character_to_lsp(symbol, String.length(symbol))
491+
end_char = SourceFile.elixir_character_to_lsp(symbol, String.length(to_string(symbol)))
485492
{start_line, start_character + end_char + 1}
486493

487494
parent_end_line =
@@ -537,30 +544,17 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do
537544
"[" <> list_stringified <> "]"
538545
end
539546

540-
defp extract_module_name({:__aliases__, location, [head | tail]}) when not is_atom(head) do
541-
extract_module_name(head) <> "." <> extract_module_name({:__aliases__, location, tail})
542-
end
543-
544-
defp extract_module_name({:__aliases__, _location, module_names}) do
545-
if Enum.all?(module_names, &is_atom/1) do
546-
Enum.join(module_names, ".")
547-
else
548-
"# unknown"
549-
end
550-
end
551-
552-
defp extract_module_name({:__MODULE__, _location, nil}) do
553-
"__MODULE__"
554-
end
555-
556547
defp extract_module_name(module) when is_atom(module) do
557548
case Atom.to_string(module) do
558-
"Elixir." <> elixir_module_rest -> elixir_module_rest
559-
erlang_module -> erlang_module
549+
"Elixir." <> elixir_module_rest ->
550+
elixir_module_rest
551+
552+
erlang_module ->
553+
erlang_module
560554
end
561555
end
562556

563-
defp extract_module_name(_), do: "# unknown"
557+
defp extract_module_name(other), do: Macro.to_string(other)
564558

565559
defp extract_property(property_name, location) when is_atom(property_name) do
566560
%Info{

apps/language_server/lib/language_server/server.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1305,7 +1305,7 @@ defmodule ElixirLS.LanguageServer.Server do
13051305
"referencesProvider" => true,
13061306
"documentFormattingProvider" => true,
13071307
"signatureHelpProvider" => %{"triggerCharacters" => SignatureHelp.trigger_characters()},
1308-
"documentSymbolProvider" => true,
1308+
"documentSymbolProvider" => %{"label" => "Elixir outline"},
13091309
"workspaceSymbolProvider" => true,
13101310
"documentOnTypeFormattingProvider" => %{"firstTriggerCharacter" => "\n"},
13111311
"codeLensProvider" => %{"resolveProvider" => false},
@@ -1889,6 +1889,8 @@ defmodule ElixirLS.LanguageServer.Server do
18891889
%{}
18901890
)
18911891

1892+
# :observer.start()
1893+
18921894
trigger_build(state)
18931895
end
18941896

0 commit comments

Comments
 (0)