Show deprecated and since doc metadata on mouse over (#852)

* Show deprecated and since doc metadata on mouse over

* Make deprecated indication stronger

Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>

Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
This commit is contained in:
Milo Lee 2022-01-12 02:18:47 +08:00 committed by GitHub
parent 24668c6edb
commit 8ba0857369
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 13 deletions

View file

@ -121,7 +121,8 @@ defmodule Livebook.Intellisense do
defp include_in_completion?({:module, _module, _display_name, :hidden}), do: false
defp include_in_completion?(
{:function, _module, _name, _arity, _type, _display_name, :hidden, _signatures, _specs}
{:function, _module, _name, _arity, _type, _display_name, :hidden, _signatures, _specs,
_meta}
),
do: false
@ -188,7 +189,8 @@ defmodule Livebook.Intellisense do
end
defp format_completion_item(
{:function, module, name, arity, type, display_name, documentation, signatures, specs}
{:function, module, name, arity, type, display_name, documentation, signatures, specs,
_meta}
),
do: %{
label: "#{display_name}/#{arity}",
@ -380,10 +382,13 @@ defmodule Livebook.Intellisense do
end
defp format_details_item(
{:function, module, name, _arity, _type, _display_name, documentation, signatures, specs}
{:function, module, name, _arity, _type, _display_name, documentation, signatures, specs,
meta}
) do
join_with_divider([
format_signatures(signatures, module) |> code(),
format_meta(:since, meta),
format_meta(:deprecated, meta),
format_specs(specs, name, @extended_line_length) |> code(),
format_documentation(documentation, :all)
])
@ -439,6 +444,16 @@ defmodule Livebook.Intellisense do
end
end
defp format_meta(:deprecated, %{deprecated: deprecated}) do
"**Deprecated**. " <> deprecated
end
defp format_meta(:since, %{since: since}) do
"Since " <> since
end
defp format_meta(_, _), do: nil
defp format_specs([], _name, _line_length), do: nil
defp format_specs(specs, name, line_length) do

View file

@ -10,7 +10,8 @@ defmodule Livebook.Intellisense.Docs do
arity: non_neg_integer(),
documentation: documentation(),
signatures: list(signature()),
specs: list(spec())
specs: list(spec()),
meta: meta()
}
@type member_kind :: :function | :macro | :type
@ -19,6 +20,8 @@ defmodule Livebook.Intellisense.Docs do
@type signature :: String.t()
@type meta :: map()
@typedoc """
A single spec annotation in the Erlang Abstract Format.
"""
@ -88,7 +91,8 @@ defmodule Livebook.Intellisense.Docs do
arity: arity,
documentation: documentation(doc, format),
signatures: signatures,
specs: Map.get(specs, {name, base_arity}, [])
specs: Map.get(specs, {name, base_arity}, []),
meta: meta
}
_ ->

View file

@ -24,7 +24,7 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
| {:in_struct_field, module(), name(), default :: value()}
| {:module, module(), display_name(), Docs.documentation()}
| {:function, module(), name(), arity(), function_type(), display_name(),
Docs.documentation(), list(Docs.signature()), list(Docs.spec())}
Docs.documentation(), list(Docs.signature()), list(Docs.spec()), Docs.meta()}
| {:type, module(), name(), arity(), Docs.documentation()}
| {:module_attribute, name(), Docs.documentation()}
@ -316,12 +316,13 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
defp match_sigil(hint, ctx) do
for {:function, module, name, arity, type, "sigil_" <> sigil_name, documentation, signatures,
specs} <-
specs,
meta} <-
match_local("sigil_", %{ctx | matcher: @prefix_matcher}),
ctx.matcher.(sigil_name, hint),
do:
{:function, module, name, arity, type, "~" <> sigil_name, documentation, signatures,
specs}
specs, meta}
end
defp match_erlang_module(hint, ctx) do
@ -467,12 +468,16 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
Enum.map(matching_funs, fn {name, arity, type} ->
doc_item =
Enum.find(doc_items, %{documentation: nil, signatures: [], specs: []}, fn doc_item ->
doc_item.name == name && doc_item.arity == arity
end)
Enum.find(
doc_items,
%{documentation: nil, signatures: [], specs: [], meta: %{}},
fn doc_item ->
doc_item.name == name && doc_item.arity == arity
end
)
{:function, mod, name, arity, type, Atom.to_string(name),
doc_item && doc_item.documentation, doc_item.signatures, doc_item.specs}
{:function, mod, name, arity, type, Atom.to_string(name), doc_item.documentation,
doc_item.signatures, doc_item.specs, doc_item.meta}
end)
else
[]

View file

@ -1217,6 +1217,20 @@ defmodule Livebook.IntellisenseTest do
assert content =~ "## Examples"
end
test "returns deprecated docs" do
{binding, env} = eval(do: nil)
assert %{contents: [content | _]} = Intellisense.get_details("Enum.chunk", 6, binding, env)
assert content =~ "Use Enum.chunk_every/2 instead"
end
test "returns since docs" do
{binding, env} = eval(do: nil)
assert %{contents: [content]} = Intellisense.get_details("then", 2, binding, env)
assert content =~ "Since 1.12.0"
end
@tag :erl_docs
test "returns full Erlang docs" do
{binding, env} = eval(do: nil)