Skip to content

Commit c66fdfb

Browse files
committed
feat: add active parameter
1 parent c3f0257 commit c66fdfb

File tree

4 files changed

+248
-142
lines changed

4 files changed

+248
-142
lines changed

lib/next_ls.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,8 @@ defmodule NextLS do
781781
text = Enum.join(lsp.assigns.documents[uri], "\n")
782782

783783
signature_help =
784-
case SignatureHelp.fetch_mod_and_name(text, {position.line + 1, position.character + 1}) do
785-
{:ok, {mod, name}} ->
784+
case SignatureHelp.fetch(text, {position.line + 1, position.character + 1}) do
785+
{:ok, {mod, name, param_index}} ->
786786
docs =
787787
dispatch(lsp.assigns.registry, :runtimes, fn entries ->
788788
[result] =
@@ -794,7 +794,7 @@ defmodule NextLS do
794794
end)
795795

796796
docs
797-
|> SignatureHelp.format(name)
797+
|> SignatureHelp.format(name, param_index)
798798
|> List.first()
799799

800800
{:error, :not_found} ->

lib/next_ls/helpers/ast_helpers.ex

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,11 @@ defmodule NextLS.ASTHelpers do
178178
ast
179179
|> Zipper.zip()
180180
|> Zipper.find(fn
181-
{{:., _, _}, _metadata, _} = node ->
182-
range = Sourceror.get_range(node)
181+
{:|>, _, [_, {{:., _, _}, _metadata, _} = func_node]} ->
182+
inside?(func_node, position)
183183

184-
Sourceror.compare_positions(range.start, position) == :lt &&
185-
Sourceror.compare_positions(range.end, position) == :gt
184+
{{:., _, _}, _metadata, _} = node ->
185+
inside?(node, position)
186186

187187
_ ->
188188
false
@@ -194,5 +194,25 @@ defmodule NextLS.ASTHelpers do
194194
{:error, :not_found}
195195
end
196196
end
197+
198+
def find_params_index(ast, {line, column}) do
199+
ast
200+
|> Sourceror.get_args()
201+
|> Enum.map(&Sourceror.get_meta/1)
202+
|> Enum.find_index(fn meta ->
203+
if meta[:closing] do
204+
line <= meta[:closing][:line] and line >= meta[:line]
205+
else
206+
meta[:line] == line and column <= meta[:column]
207+
end
208+
end)
209+
end
210+
211+
defp inside?(node, position) do
212+
range = Sourceror.get_range(node)
213+
214+
Sourceror.compare_positions(range.start, position) == :lt &&
215+
Sourceror.compare_positions(range.end, position) == :gt
216+
end
197217
end
198218
end

lib/next_ls/signature_help.ex

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ defmodule NextLS.SignatureHelp do
88
alias GenLSP.Structures.SignatureInformation
99
alias NextLS.ASTHelpers
1010

11-
def fetch_mod_and_name(text, position) do
11+
def fetch(text, position) do
1212
ast =
1313
text
1414
|> Spitfire.parse(literal_encoder: &{:ok, {:__literal__, &2, [&1]}})
@@ -19,37 +19,56 @@ defmodule NextLS.SignatureHelp do
1919

2020
with {:ok, result} <- ASTHelpers.Function.find_remote_function_call_within(ast, position) do
2121
case result do
22-
{{:., _, [{:__aliases__, _, modules}, name]}, _, _} -> {:ok, {Module.concat(modules), name}}
22+
{:|>, _, [_, {{:., _, [{:__aliases__, _, modules}, name]}, _, _} = node]} ->
23+
param_index = ASTHelpers.Function.find_params_index(node, position)
24+
25+
if param_index do
26+
{:ok, {Module.concat(modules), name, param_index + 1}}
27+
else
28+
{:ok, {Module.concat(modules), name, nil}}
29+
end
30+
31+
{{:., _, [{:__aliases__, _, modules}, name]}, _, _} = node ->
32+
param_index = ASTHelpers.Function.find_params_index(node, position)
33+
34+
{:ok, {Module.concat(modules), name, param_index}}
35+
36+
_otherwise ->
37+
{:error, :not_found}
2338
end
2439
end
2540
end
2641

27-
def format({:ok, {:docs_v1, _, _lang, content_type, _, _, docs}}, func_name) do
42+
def format({:ok, {:docs_v1, _, _lang, content_type, _, _, docs}}, func_name, param_index) do
2843
for {{_, name, _arity}, _, [signature], fdoc, _} <- docs, name == func_name do
2944
params_info =
3045
signature
3146
|> Spitfire.parse!()
32-
|> then(fn {_, _, args} ->
33-
Enum.map(args, fn {name, _, _} ->
34-
%ParameterInformation{
35-
label: Atom.to_string(name)
36-
}
37-
end)
47+
|> Sourceror.get_args()
48+
|> Enum.map(fn {name, _, _} ->
49+
%ParameterInformation{
50+
label: Atom.to_string(name)
51+
}
3852
end)
3953

4054
%SignatureHelp{
4155
signatures: [
4256
%SignatureInformation{
4357
label: signature,
4458
parameters: params_info,
45-
documentation: maybe_doc(content_type, fdoc)
59+
documentation: maybe_doc(content_type, fdoc),
60+
active_parameter: param_index
4661
}
4762
]
4863
}
4964
end
5065
end
5166

52-
def format({:ok, {:error, :module_not_found}}, _func_name) do
67+
def format({:ok, {:error, :module_not_found}}, _func_name, _param_index) do
68+
[]
69+
end
70+
71+
def format({:error, :not_ready}, _func_name, _param_index) do
5372
[]
5473
end
5574

0 commit comments

Comments
 (0)