Skip to content

Commit

Permalink
feat: add active parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
lucacervello committed Apr 23, 2024
1 parent 042435d commit 8bb60aa
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 142 deletions.
6 changes: 3 additions & 3 deletions lib/next_ls.ex
Original file line number Diff line number Diff line change
Expand Up @@ -831,8 +831,8 @@ defmodule NextLS do
text = Enum.join(lsp.assigns.documents[uri], "\n")

signature_help =
case SignatureHelp.fetch_mod_and_name(text, {position.line + 1, position.character + 1}) do
{:ok, {mod, name}} ->
case SignatureHelp.fetch(text, {position.line + 1, position.character + 1}) do
{:ok, {mod, name, param_index}} ->
docs =
dispatch(lsp.assigns.registry, :runtimes, fn entries ->
[result] =
Expand All @@ -844,7 +844,7 @@ defmodule NextLS do
end)

docs
|> SignatureHelp.format(name)
|> SignatureHelp.format(name, param_index)
|> List.first()

{:error, :not_found} ->
Expand Down
28 changes: 24 additions & 4 deletions lib/next_ls/helpers/ast_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,11 @@ defmodule NextLS.ASTHelpers do
ast
|> Zipper.zip()
|> Zipper.find(fn
{{:., _, _}, _metadata, _} = node ->
range = Sourceror.get_range(node)
{:|>, _, [_, {{:., _, _}, _metadata, _} = func_node]} ->
inside?(func_node, position)

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

_ ->
false
Expand All @@ -220,5 +220,25 @@ defmodule NextLS.ASTHelpers do
{:error, :not_found}
end
end

def find_params_index(ast, {line, column}) do
ast
|> Sourceror.get_args()
|> Enum.map(&Sourceror.get_meta/1)
|> Enum.find_index(fn meta ->
if meta[:closing] do
line <= meta[:closing][:line] and line >= meta[:line]
else
meta[:line] == line and column <= meta[:column]
end
end)
end

defp inside?(node, position) do
range = Sourceror.get_range(node)

Sourceror.compare_positions(range.start, position) == :lt &&
Sourceror.compare_positions(range.end, position) == :gt
end
end
end
41 changes: 30 additions & 11 deletions lib/next_ls/signature_help.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule NextLS.SignatureHelp do
alias GenLSP.Structures.SignatureInformation
alias NextLS.ASTHelpers

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

with {:ok, result} <- ASTHelpers.Function.find_remote_function_call_within(ast, position) do
case result do
{{:., _, [{:__aliases__, _, modules}, name]}, _, _} -> {:ok, {Module.concat(modules), name}}
{:|>, _, [_, {{:., _, [{:__aliases__, _, modules}, name]}, _, _} = node]} ->
param_index = ASTHelpers.Function.find_params_index(node, position)

if param_index do
{:ok, {Module.concat(modules), name, param_index + 1}}
else
{:ok, {Module.concat(modules), name, nil}}
end

{{:., _, [{:__aliases__, _, modules}, name]}, _, _} = node ->
param_index = ASTHelpers.Function.find_params_index(node, position)

{:ok, {Module.concat(modules), name, param_index}}

_otherwise ->
{:error, :not_found}
end
end
end

def format({:ok, {:docs_v1, _, _lang, content_type, _, _, docs}}, func_name) do
def format({:ok, {:docs_v1, _, _lang, content_type, _, _, docs}}, func_name, param_index) do
for {{_, name, _arity}, _, [signature], fdoc, _} <- docs, name == func_name do
params_info =
signature
|> Spitfire.parse!()
|> then(fn {_, _, args} ->
Enum.map(args, fn {name, _, _} ->
%ParameterInformation{
label: Atom.to_string(name)
}
end)
|> Sourceror.get_args()
|> Enum.map(fn {name, _, _} ->
%ParameterInformation{
label: Atom.to_string(name)
}
end)

%SignatureHelp{
signatures: [
%SignatureInformation{
label: signature,
parameters: params_info,
documentation: maybe_doc(content_type, fdoc)
documentation: maybe_doc(content_type, fdoc),
active_parameter: param_index
}
]
}
end
end

def format({:ok, {:error, :module_not_found}}, _func_name) do
def format({:ok, {:error, :module_not_found}}, _func_name, _param_index) do
[]
end

def format({:error, :not_ready}, _func_name, _param_index) do
[]
end

Expand Down
Loading

0 comments on commit 8bb60aa

Please sign in to comment.