Improve completion (#756)

* Don't show variable value in intellisense

* Don't complete quoted atoms
This commit is contained in:
Jonatan Kłosko 2021-12-05 16:49:51 +01:00 committed by GitHub
parent be3225fe3a
commit b97cde0879
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 45 deletions

View file

@ -127,21 +127,21 @@ defmodule Livebook.Intellisense do
defp include_in_completion?(_), do: true
defp format_completion_item({:variable, name, value}),
defp format_completion_item({:variable, name, _value}),
do: %{
label: name,
kind: :variable,
detail: "variable",
documentation: value_snippet(value, @line_length),
documentation: nil,
insert_text: name
}
defp format_completion_item({:map_field, name, value}),
defp format_completion_item({:map_field, name, _value}),
do: %{
label: name,
kind: :field,
detail: "field",
documentation: value_snippet(value, @line_length),
documentation: nil,
insert_text: name
}
@ -336,18 +336,9 @@ defmodule Livebook.Intellisense do
end
end
defp format_details_item({:variable, name, value}) do
join_with_divider([
code(name),
value_snippet(value, @extended_line_length)
])
end
defp format_details_item({:variable, name, _value}), do: code(name)
defp format_details_item({:map_field, _name, value}) do
join_with_divider([
value_snippet(value, @extended_line_length)
])
end
defp format_details_item({:map_field, name, _value}), do: code(name)
defp format_details_item({:module, _module, display_name, documentation}) do
join_with_divider([
@ -403,14 +394,6 @@ defmodule Livebook.Intellisense do
"""
end
defp value_snippet(value, line_length) do
"""
```
#{inspect(value, pretty: true, width: line_length)}
```\
"""
end
defp format_signatures([], _module), do: nil
defp format_signatures(signatures, module) do

View file

@ -341,7 +341,7 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
defp valid_alias_rest?(rest), do: valid_alias_piece?(rest)
defp usable_as_unquoted_module?(mod) do
Code.Identifier.classify(mod) != :other
macro_classify_atom(mod) in [:identifier, :unquoted]
end
defp get_matching_modules(hint, ctx) do
@ -484,4 +484,70 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
ctx.matcher.(name, hint),
do: {:module_attribute, name, {"text/markdown", info.doc}}
end
# ---
# TODO use Macro.classify_atom/1 on Elixir 1.14
def macro_classify_atom(atom) do
case macro_inner_classify(atom) do
:alias -> :alias
:identifier -> :identifier
type when type in [:unquoted_operator, :not_callable] -> :unquoted
_ -> :quoted
end
end
defp macro_inner_classify(atom) when is_atom(atom) do
cond do
atom in [:%, :%{}, :{}, :<<>>, :..., :.., :., :"..//", :->] ->
:not_callable
atom in [:"::"] ->
:quoted_operator
Macro.operator?(atom, 1) or Macro.operator?(atom, 2) ->
:unquoted_operator
true ->
charlist = Atom.to_charlist(atom)
if macro_valid_alias?(charlist) do
:alias
else
case :elixir_config.identifier_tokenizer().tokenize(charlist) do
{kind, _acc, [], _, _, special} ->
if kind == :identifier and not :lists.member(?@, special) do
:identifier
else
:not_callable
end
_ ->
:other
end
end
end
end
defp macro_valid_alias?('Elixir' ++ rest), do: macro_valid_alias_piece?(rest)
defp macro_valid_alias?(_other), do: false
defp macro_valid_alias_piece?([?., char | rest]) when char >= ?A and char <= ?Z,
do: macro_valid_alias_piece?(macro_trim_leading_while_valid_identifier(rest))
defp macro_valid_alias_piece?([]), do: true
defp macro_valid_alias_piece?(_other), do: false
defp macro_trim_leading_while_valid_identifier([char | rest])
when char >= ?a and char <= ?z
when char >= ?A and char <= ?Z
when char >= ?0 and char <= ?9
when char == ?_ do
macro_trim_leading_while_valid_identifier(rest)
end
defp macro_trim_leading_while_valid_identifier(other) do
other
end
end

View file

@ -112,6 +112,13 @@ defmodule Livebook.IntellisenseTest do
assert lists_item in Intellisense.get_completion_items(" :", binding, env)
end
@tag :erl_docs
test "Erlang completion doesn't include quoted atoms" do
{binding, env} = eval(do: nil)
assert [] = Intellisense.get_completion_items(~s{:Elixir}, binding, env)
end
@tag :erl_docs
test "Erlang module completion with 'in' operator in spec" do
{binding, env} = eval(do: nil)
@ -589,21 +596,21 @@ defmodule Livebook.IntellisenseTest do
label: "bar_1",
kind: :field,
detail: "field",
documentation: ~s{```\n~r/pattern/\n```},
documentation: nil,
insert_text: "bar_1"
},
%{
label: "bar_2",
kind: :field,
detail: "field",
documentation: ~s{```\ntrue\n```},
documentation: nil,
insert_text: "bar_2"
},
%{
label: "foo",
kind: :field,
detail: "field",
documentation: ~s{```\n1\n```},
documentation: nil,
insert_text: "foo"
}
] = Intellisense.get_completion_items("map.", binding, env)
@ -613,7 +620,7 @@ defmodule Livebook.IntellisenseTest do
label: "foo",
kind: :field,
detail: "field",
documentation: ~s{```\n1\n```},
documentation: nil,
insert_text: "foo"
}
] = Intellisense.get_completion_items("map.f", binding, env)
@ -639,18 +646,7 @@ defmodule Livebook.IntellisenseTest do
label: "nested",
kind: :field,
detail: "field",
documentation: """
```
%{
deeply: %{
bar_1: 23,
bar_2: 14,
foo: 1,
mod: System
}
}
```\
""",
documentation: nil,
insert_text: "nested"
}
] = Intellisense.get_completion_items("map.nest", binding, env)
@ -660,7 +656,7 @@ defmodule Livebook.IntellisenseTest do
label: "foo",
kind: :field,
detail: "field",
documentation: ~s{```\n1\n```},
documentation: nil,
insert_text: "foo"
}
] = Intellisense.get_completion_items("map.nested.deeply.f", binding, env)
@ -787,7 +783,7 @@ defmodule Livebook.IntellisenseTest do
label: "numbats",
kind: :variable,
detail: "variable",
documentation: ~s{```\n["numbat", "numbat"]\n```},
documentation: nil,
insert_text: "numbats"
}
] = Intellisense.get_completion_items("numba", binding, env)
@ -797,14 +793,14 @@ defmodule Livebook.IntellisenseTest do
label: "numbats",
kind: :variable,
detail: "variable",
documentation: ~s{```\n["numbat", "numbat"]\n```},
documentation: nil,
insert_text: "numbats"
},
%{
label: "number",
kind: :variable,
detail: "variable",
documentation: ~s{```\n3\n```},
documentation: nil,
insert_text: "number"
}
] = Intellisense.get_completion_items("num", binding, env)
@ -814,7 +810,7 @@ defmodule Livebook.IntellisenseTest do
label: "nothing",
kind: :variable,
detail: "variable",
documentation: ~s{```\nnil\n```},
documentation: nil,
insert_text: "nothing"
},
%{label: "node/0"},