From 36ce11c2111edc112efa075011c8fd9821d144c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Tue, 2 Aug 2022 11:29:45 +0200 Subject: [PATCH] Fix signature completion and signature types in older Erlang docs (#1318) --- lib/livebook/intellisense.ex | 22 +++++++++++++++-- .../intellisense/signature_matcher.ex | 3 +++ test/livebook/intellisense_test.exs | 24 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/livebook/intellisense.ex b/lib/livebook/intellisense.ex index 074061422..1e00e8f59 100644 --- a/lib/livebook/intellisense.ex +++ b/lib/livebook/intellisense.ex @@ -625,8 +625,7 @@ defmodule Livebook.Intellisense do end defp build_md(iodata, [{:ul, [{:class, "types"} | _], content} | ast]) do - lines = Enum.map(content, fn {:li, _, line} -> line end) - render_code_block(lines, "erlang") |> append_block(iodata) |> build_md(ast) + render_types_list(content) |> append_block(iodata) |> build_md(ast) end defp build_md(iodata, [{:ul, _, content} | ast]) do @@ -735,4 +734,23 @@ defmodule Livebook.Intellisense do end) |> render_unordered_list() end + + defp render_types_list(content) do + content + |> group_type_list_items([]) + |> render_unordered_list() + end + + defp group_type_list_items([], acc), do: Enum.reverse(acc) + + defp group_type_list_items([{:li, [{:class, "type"}], content} | items], acc) do + group_type_list_items(items, [{:li, [], [{:code, [], content}]} | acc]) + end + + defp group_type_list_items( + [{:li, [{:class, "description"}], content} | items], + [{:li, [], prev_content} | acc] + ) do + group_type_list_items(items, [{:li, [], prev_content ++ [{:p, [], content}]} | acc]) + end end diff --git a/lib/livebook/intellisense/signature_matcher.ex b/lib/livebook/intellisense/signature_matcher.ex index 5f01ce0bd..38dba32f8 100644 --- a/lib/livebook/intellisense/signature_matcher.ex +++ b/lib/livebook/intellisense/signature_matcher.ex @@ -68,6 +68,9 @@ defmodule Livebook.Intellisense.SignatureMatcher do end defp fix_erlang_signature(signature, specs) do + # Erlang signatures may include "->" followed by return type + signature = signature |> String.split("->") |> hd() |> String.trim() + case parse_erlang_signature(signature) do {:ok, fun, arity} -> args = diff --git a/test/livebook/intellisense_test.exs b/test/livebook/intellisense_test.exs index c89fa2ffb..497557d24 100644 --- a/test/livebook/intellisense_test.exs +++ b/test/livebook/intellisense_test.exs @@ -1224,6 +1224,14 @@ defmodule Livebook.IntellisenseTest do assert file_read =~ "Typical error reasons:" end + @tag :erl_docs + test "properly renders Erlang signature types list" do + context = eval(do: nil) + + assert %{contents: [file_read]} = Intellisense.get_details(":odbc.connect()", 8, context) + assert file_read =~ "Ref = connection_reference()" + end + test "properly parses unicode" do context = eval(do: nil) @@ -1429,6 +1437,22 @@ defmodule Livebook.IntellisenseTest do } = Intellisense.get_signature_items(":lists.map(", context) end + @tag :erl_docs + test "shows signature with arguments for erlang modules with arrow signature" do + context = eval(do: nil) + + assert %{ + active_argument: 0, + signature_items: [ + %{ + signature: "connect(ConnectStr, Options)", + arguments: ["ConnectStr", "Options"], + documentation: _connect_doc + } + ] + } = Intellisense.get_signature_items(":odbc.connect(", context) + end + test "returns call active argument" do context = eval(do: nil)