diff --git a/apps/language_server/lib/language_server/providers/document_symbols.ex b/apps/language_server/lib/language_server/providers/document_symbols.ex index b798576be..2043a06ba 100644 --- a/apps/language_server/lib/language_server/providers/document_symbols.ex +++ b/apps/language_server/lib/language_server/providers/document_symbols.ex @@ -187,7 +187,10 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do type_name = type_name - |> String.replace("\n", "") + |> String.replace(~r/,*\n\s*/u, fn + "," <> _ -> ", " + _ -> "" + end) type = if type_kind in [:type, :typep, :opaque], do: :class, else: :event @@ -220,7 +223,12 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do {defname, location, [{:when, _, [{_, head_location, _} = fn_head, _]} | _]} ) when defname in @defs do - name = Macro.to_string(fn_head) |> String.replace("\n", "") + name = + Macro.to_string(fn_head) + |> String.replace(~r/,*\n\s*/u, fn + "," <> _ -> ", " + _ -> "" + end) %Info{ type: if(defname in @macro_defs, do: :constant, else: :function), @@ -235,7 +243,12 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbols do # Function, macro, delegate defp extract_symbol(_current_module, {defname, location, [{_, head_location, _} = fn_head | _]}) when defname in @defs do - name = Macro.to_string(fn_head) |> String.replace("\n", "") + name = + Macro.to_string(fn_head) + |> String.replace(~r/,*\n\s*/u, fn + "," <> _ -> ", " + _ -> "" + end) %Info{ type: if(defname in @macro_defs, do: :constant, else: :function), diff --git a/apps/language_server/test/providers/document_symbols_test.exs b/apps/language_server/test/providers/document_symbols_test.exs index dc92cbccb..aec42c9a1 100644 --- a/apps/language_server/test/providers/document_symbols_test.exs +++ b/apps/language_server/test/providers/document_symbols_test.exs @@ -41,6 +41,17 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do def fun_multiple_when(_other) do :something_else end + def fun_multiline_args( + foo, + bar + ) + when is_atom(foo), + do: foo + def fun_multiline_args( + foo, + bar + ), + do: bar end ] @@ -196,12 +207,22 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do "end" => %{"character" => 37, "line" => 31}, "start" => %{"character" => 12, "line" => 31} } + }, + %Protocol.DocumentSymbol{ + children: [], + kind: 12, + name: "def fun_multiline_args(foo, bar)" + }, + %Protocol.DocumentSymbol{ + children: [], + kind: 12, + name: "def fun_multiline_args(foo, bar)" } ], kind: 2, name: "MyModule", range: %{ - "end" => %{"character" => 9, "line" => 34}, + "end" => %{"character" => 9, "line" => 45}, "start" => %{"character" => 6, "line" => 1} }, selectionRange: %{ @@ -238,6 +259,17 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do after :ok end + def fun_multiline_args( + foo, + bar + ) + when is_atom(foo), + do: foo + def fun_multiline_args( + foo, + bar + ), + do: bar end ] @@ -250,7 +282,7 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do kind: 2, location: %{ range: %{ - "end" => %{"character" => 9, "line" => 24}, + "end" => %{"character" => 9, "line" => 35}, "start" => %{"character" => 6, "line" => 1} } } @@ -344,6 +376,16 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do } }, containerName: "MyModule" + }, + %Protocol.SymbolInformation{ + kind: 12, + name: "def fun_multiline_args(foo, bar)", + containerName: "MyModule" + }, + %Protocol.SymbolInformation{ + kind: 12, + name: "def fun_multiline_args(foo, bar)", + containerName: "MyModule" } ]} = DocumentSymbols.symbols(uri, parser_context, false) end @@ -1215,6 +1257,10 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do @type my_with_args_when(key, value) :: [{key, value}] when value: integer @type abc @type + @type my_with_multiline_args( + key, + value + ) :: [{key, value}] end """ @@ -1271,6 +1317,11 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do children: [], kind: 22, name: "@type" + }, + %Protocol.DocumentSymbol{ + children: [], + kind: 5, + name: "@type my_with_multiline_args(key, value)" } ], kind: 2, @@ -1292,6 +1343,10 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do @type my_with_args_when(key, value) :: [{key, value}] when value: integer @type abc @type + @type my_with_multiline_args( + key, + value + ) :: [{key, value}] end """ @@ -1348,6 +1403,11 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do kind: 22, name: "@type", containerName: "MyModule" + }, + %Protocol.SymbolInformation{ + kind: 5, + name: "@type my_with_multiline_args(key, value)", + containerName: "MyModule" } ]} = DocumentSymbols.symbols(uri, parser_context, false) end @@ -2556,8 +2616,7 @@ defmodule ElixirLS.LanguageServer.Providers.DocumentSymbolsTest do parser_context = ParserContextBuilder.from_string(text) - assert {:ok, []} = - DocumentSymbols.symbols(uri, parser_context, true) + assert {:ok, []} = DocumentSymbols.symbols(uri, parser_context, true) end test "returns def and defp as a prefix" do