Skip to content

Commit 9ad535f

Browse files
lukaszsamsonaxelson
authored andcommitted
Provide completions for protocol functions (#83)
* provide completions for protocol functions * make test not depend on std lib
1 parent dfa8116 commit 9ad535f

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,34 @@ defmodule ElixirLS.LanguageServer.Providers.Completion do
285285
end
286286
end
287287

288+
defp from_completion_item(
289+
%{
290+
type: :protocol_function,
291+
args: args,
292+
spec: _spec,
293+
name: name,
294+
summary: summary,
295+
arity: arity,
296+
origin: origin
297+
},
298+
context
299+
) do
300+
def_str = if(context[:def_before] == nil, do: "def ")
301+
302+
full_snippet = "#{def_str}#{snippet(name, args, arity)} do\n\t$0\nend"
303+
label = "#{def_str}#{function_label(name, args, arity)}"
304+
305+
%__MODULE__{
306+
label: label,
307+
kind: :interface,
308+
detail: "#{origin} protocol function",
309+
documentation: summary,
310+
insert_text: full_snippet,
311+
priority: 2,
312+
filter_text: name
313+
}
314+
end
315+
288316
defp from_completion_item(%{type: :field, name: name, origin: origin}, _context) do
289317
%__MODULE__{
290318
label: to_string(name),

apps/language_server/mix.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ defmodule ElixirLS.LanguageServer.Mixfile do
1010
config_path: "config/config.exs",
1111
deps_path: "../../deps",
1212
lockfile: "../../mix.lock",
13+
elixirc_paths: elixirc_paths(Mix.env()),
1314
build_embedded: false,
1415
start_permanent: true,
1516
build_per_environment: false,
@@ -31,4 +32,7 @@ defmodule ElixirLS.LanguageServer.Mixfile do
3132
{:dialyxir, "~> 1.0.0-rc.6", runtime: false}
3233
]
3334
end
35+
36+
defp elixirc_paths(:test), do: ["lib", "test/support"]
37+
defp elixirc_paths(_), do: ["lib"]
3438
end

apps/language_server/test/providers/completion_test.exs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,26 @@ defmodule ElixirLS.LanguageServer.Providers.CompletionTest do
5555
assert(Enum.any?(items, fn %{"label" => label} -> label == lfn end))
5656
end
5757
end
58+
59+
test "provides completions for protocol functions" do
60+
text = """
61+
defimpl ElixirLS.LanguageServer.Fixtures.ExampleProtocol, for: MyModule do
62+
63+
#^
64+
end
65+
"""
66+
67+
{line, char} = {1, 1}
68+
TestUtils.assert_has_cursor_char(text, line, char)
69+
{:ok, %{"items" => items}} = Completion.completion(text, line, char, true)
70+
71+
completions =
72+
items
73+
|> Enum.filter(&(&1["detail"] =~ "protocol function"))
74+
|> Enum.map(& &1["label"])
75+
76+
assert completions == [
77+
"def my_fun(example,arg)"
78+
]
79+
end
5880
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
defprotocol ElixirLS.LanguageServer.Fixtures.ExampleProtocol do
2+
@moduledoc """
3+
ExampleProtocol protocol used in tests.
4+
"""
5+
6+
@doc """
7+
Does what `my_fun` does for `t`
8+
"""
9+
@spec my_fun(t, integer) :: binary
10+
def my_fun(example, arg)
11+
end

0 commit comments

Comments
 (0)