Skip to content

Commit 3b5a43c

Browse files
msaraivaaxelson
andauthored
Properly handle callback suggestion (#265)
* Property handle callback suggestion * Fix snippet not adding arguments for callbacks * Add tests for callback completion * Update elixir_sense and make tests not depend on stdlib Co-authored-by: Jason Axelson <jason.axelson@gmail.com>
1 parent fb6241c commit 3b5a43c

File tree

4 files changed

+60
-4
lines changed

4 files changed

+60
-4
lines changed

apps/language_server/lib/language_server/providers/completion.ex

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,21 @@ defmodule ElixirLS.LanguageServer.Providers.Completion do
281281
insert_text = def_snippet(def_str, name, args, arity, options)
282282
label = "#{def_str}#{function_label(name, args, arity)}"
283283

284+
filter_text =
285+
if def_str do
286+
"#{def_str}#{name}"
287+
else
288+
name
289+
end
290+
284291
%__MODULE__{
285292
label: label,
286293
kind: :interface,
287294
detail: "#{origin} callback",
288295
documentation: summary,
289296
insert_text: insert_text,
290297
priority: 2,
291-
filter_text: name,
298+
filter_text: filter_text,
292299
tags: metadata_to_tags(metadata)
293300
}
294301
end
@@ -437,13 +444,13 @@ defmodule ElixirLS.LanguageServer.Providers.Completion do
437444

438445
defp def_snippet(def_str, name, args, arity, opts) do
439446
if Keyword.get(opts, :snippets_supported, false) do
440-
"#{def_str}#{function_snippet(name, args, arity)} do\n\t$0\nend"
447+
"#{def_str}#{function_snippet(name, args, arity, opts)} do\n\t$0\nend"
441448
else
442449
"#{def_str}#{name}"
443450
end
444451
end
445452

446-
defp function_snippet(name, args, arity, opts \\ []) do
453+
defp function_snippet(name, args, arity, opts) do
447454
cond do
448455
Keyword.get(opts, :capture_before?) && arity <= 1 ->
449456
Enum.join([name, "/", arity])

apps/language_server/test/providers/completion_test.exs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,51 @@ defmodule ElixirLS.LanguageServer.Providers.CompletionTest do
138138
]
139139
end
140140

141+
test "provides completions for callbacks without `def` before" do
142+
text = """
143+
defmodule MyModule do
144+
@behaviour ElixirLS.LanguageServer.Fixtures.ExampleBehaviour
145+
146+
# ^
147+
end
148+
"""
149+
150+
{line, char} = {2, 2}
151+
TestUtils.assert_has_cursor_char(text, line, char)
152+
{:ok, %{"items" => items}} = Completion.completion(text, line, char, @supports)
153+
154+
first_completion =
155+
items
156+
|> Enum.filter(&(&1["detail"] =~ "callback"))
157+
|> Enum.at(0)
158+
159+
assert first_completion["label"] =~ "def build_greeting"
160+
161+
assert first_completion["insertText"] == "def build_greeting(${1:name}) do\n\t$0\nend"
162+
end
163+
164+
test "provides completions for callbacks with `def` before" do
165+
text = """
166+
defmodule MyModule do
167+
@behaviour ElixirLS.LanguageServer.Fixtures.ExampleBehaviour
168+
169+
def
170+
# ^
171+
end
172+
"""
173+
174+
{line, char} = {3, 5}
175+
TestUtils.assert_has_cursor_char(text, line, char)
176+
{:ok, %{"items" => items}} = Completion.completion(text, line, char, @supports)
177+
178+
first_completion =
179+
items
180+
|> Enum.filter(&(&1["detail"] =~ "callback"))
181+
|> Enum.at(0)
182+
183+
assert first_completion["label"] =~ "def build_greeting"
184+
end
185+
141186
test "returns module completions after pipe" do
142187
text = """
143188
defmodule MyModule do
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule ElixirLS.LanguageServer.Fixtures.ExampleBehaviour do
2+
@callback greet_world() :: nil
3+
@callback build_greeting(name :: String.t()) :: String.t()
4+
end

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%{
22
"dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
33
"docsh": {:hex, :docsh, "0.7.2", "f893d5317a0e14269dd7fe79cf95fb6b9ba23513da0480ec6e77c73221cae4f2", [:rebar3], [{:providers, "1.8.1", [hex: :providers, repo: "hexpm", optional: false]}], "hexpm", "4e7db461bb07540d2bc3d366b8513f0197712d0495bb85744f367d3815076134"},
4-
"elixir_sense": {:git, "https://github.com/elixir-lsp/elixir_sense.git", "6395dd568e542a8b05a2d3dee61f02142564f30d", []},
4+
"elixir_sense": {:git, "https://github.com/elixir-lsp/elixir_sense.git", "648a501c42c16a610cb67c29f0beb0c087171849", []},
55
"erl2ex": {:git, "https://github.com/dazuma/erl2ex.git", "244c2d9ed5805ef4855a491d8616b8842fef7ca4", []},
66
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
77
"forms": {:hex, :forms, "0.0.1", "45f3b10b6f859f95f2c2c1a1de244d63855296d55ed8e93eb0dd116b3e86c4a6", [:rebar3], [], "hexpm", "530f63ed8ed5a171f744fc75bd69cb2e36496899d19dbef48101b4636b795868"},

0 commit comments

Comments
 (0)