From b4e4c6482064a2ff63e1206df6f39007c601b5cf Mon Sep 17 00:00:00 2001 From: awerment Date: Mon, 12 Jun 2023 22:45:47 +0200 Subject: [PATCH] Show more details in type completion items (#1975) --- lib/livebook/intellisense.ex | 18 +++-- .../intellisense/signature_matcher.ex | 3 +- test/livebook/intellisense_test.exs | 70 +++++++++++++++---- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/lib/livebook/intellisense.ex b/lib/livebook/intellisense.ex index 456cb4b30..0433ae989 100644 --- a/lib/livebook/intellisense.ex +++ b/lib/livebook/intellisense.ex @@ -254,16 +254,26 @@ defmodule Livebook.Intellisense do defp format_completion_item(%{ kind: :type, + module: module, name: name, arity: arity, - documentation: documentation + documentation: documentation, + type_spec: type_spec }), do: %{ label: "#{name}/#{arity}", kind: :type, - detail: "typespec", - documentation: format_documentation(documentation, :short), - insert_text: Atom.to_string(name) + detail: format_type_signature(type_spec, module), + documentation: + join_with_newlines([ + format_documentation(documentation, :short), + format_type_spec(type_spec, @line_length) |> code() + ]), + insert_text: + cond do + arity == 0 -> "#{Atom.to_string(name)}()" + true -> "#{Atom.to_string(name)}($0)" + end } defp format_completion_item(%{kind: :module_attribute, name: name, documentation: documentation}), diff --git a/lib/livebook/intellisense/signature_matcher.ex b/lib/livebook/intellisense/signature_matcher.ex index 38dba32f8..2e57b0423 100644 --- a/lib/livebook/intellisense/signature_matcher.ex +++ b/lib/livebook/intellisense/signature_matcher.ex @@ -53,7 +53,8 @@ defmodule Livebook.Intellisense.SignatureMatcher do end defp signature_infos_for_members(mod, funs, active_argument) do - infos = Livebook.Intellisense.Docs.lookup_module_members(mod, funs, kind: [:function, :macro]) + infos = + Livebook.Intellisense.Docs.lookup_module_members(mod, funs, kinds: [:function, :macro]) for info <- infos, info.arity >= active_argument + 1 do diff --git a/test/livebook/intellisense_test.exs b/test/livebook/intellisense_test.exs index 88b8f1061..2b1fdd9e1 100644 --- a/test/livebook/intellisense_test.exs +++ b/test/livebook/intellisense_test.exs @@ -142,6 +142,41 @@ defmodule Livebook.IntellisenseTest do ] = Intellisense.get_completion_items(":erlang.open_por", context) end + @tag :erl_docs + test "Erlang type completion" do + context = eval(do: nil) + + items = Intellisense.get_completion_items(":maps.iterator", context) + + assert %{ + label: "iterator/0", + kind: :type, + detail: ":maps.iterator()", + documentation: """ + No documentation available + + ``` + @type iterator() :: iterator(term(), term()) + ```\ + """, + insert_text: "iterator()" + } in items + + assert %{ + label: "iterator/2", + kind: :type, + detail: ":maps.iterator(key, value)", + documentation: """ + An iterator representing the associations in a map with keys of type `Key` and values of type `Value`. + + ``` + @opaque iterator(key, value) + ```\ + """, + insert_text: "iterator($0)" + } in items + end + test "Elixir proxy" do context = eval(do: nil) @@ -214,28 +249,33 @@ defmodule Livebook.IntellisenseTest do %{ label: "from/0", kind: :type, - detail: "typespec", - documentation: "Tuple describing the client of a call request.", - insert_text: "from" + detail: "GenServer.from()", + documentation: """ + Tuple describing the client of a call request. + + ``` + @type from() :: {pid(), tag :: term()} + ```\ + """, + insert_text: "from()" } ] = Intellisense.get_completion_items("GenServer.fr", context) assert [ %{ - label: "name/0", + label: "internal/1", kind: :type, - detail: "typespec", - documentation: _name_doc, - insert_text: "name" - }, - %{ - label: "name_all/0", - kind: :type, - detail: "typespec", - documentation: _name_all_doc, - insert_text: "name_all" + detail: "MapSet.internal(value)", + documentation: """ + No documentation available + + ``` + @opaque internal(value) + ```\ + """, + insert_text: "internal($0)" } - ] = Intellisense.get_completion_items(":file.nam", context) + ] = Intellisense.get_completion_items("MapSet.intern", context) end test "Elixir module completion with self" do