mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-10 23:14:35 +08:00
Add completion for bitstring modifiers (#1291)
Co-authored-by: José Valim <jose.valim@gmail.com> Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
This commit is contained in:
parent
895373e08b
commit
648edf23e7
3 changed files with 118 additions and 2 deletions
|
@ -266,6 +266,23 @@ defmodule Livebook.Intellisense do
|
|||
insert_text: Atom.to_string(name)
|
||||
}
|
||||
|
||||
defp format_completion_item(%{kind: :bitstring_modifier, name: name, arity: arity}) do
|
||||
insert_text =
|
||||
if arity == 0 do
|
||||
Atom.to_string(name)
|
||||
else
|
||||
"#{name}($0)"
|
||||
end
|
||||
|
||||
%{
|
||||
label: Atom.to_string(name),
|
||||
kind: :bitstring_option,
|
||||
detail: "bitstring option",
|
||||
documentation: nil,
|
||||
insert_text: insert_text
|
||||
}
|
||||
end
|
||||
|
||||
defp keyword_macro?(name) do
|
||||
def? = name |> Atom.to_string() |> String.starts_with?("def")
|
||||
|
||||
|
@ -346,7 +363,17 @@ defmodule Livebook.Intellisense do
|
|||
end
|
||||
end
|
||||
|
||||
@ordered_kinds [:keyword, :field, :variable, :module, :struct, :interface, :function, :type]
|
||||
@ordered_kinds [
|
||||
:keyword,
|
||||
:field,
|
||||
:variable,
|
||||
:module,
|
||||
:struct,
|
||||
:interface,
|
||||
:function,
|
||||
:type,
|
||||
:bitstring_option
|
||||
]
|
||||
|
||||
defp completion_item_priority(%{kind: :struct, detail: "exception"} = completion_item) do
|
||||
{length(@ordered_kinds), completion_item.label}
|
||||
|
|
|
@ -65,6 +65,11 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
name: name(),
|
||||
documentation: Docs.documentation()
|
||||
}
|
||||
| %{
|
||||
kind: :bitstring_modifier,
|
||||
name: name(),
|
||||
arity: integer()
|
||||
}
|
||||
|
||||
@type name :: atom()
|
||||
@type display_name :: String.t()
|
||||
|
@ -72,6 +77,23 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
@exact_matcher &Kernel.==/2
|
||||
@prefix_matcher &String.starts_with?/2
|
||||
|
||||
@bitstring_modifiers [
|
||||
{:big, 0},
|
||||
{:binary, 0},
|
||||
{:bitstring, 0},
|
||||
{:integer, 0},
|
||||
{:float, 0},
|
||||
{:little, 0},
|
||||
{:native, 0},
|
||||
{:signed, 0},
|
||||
{:size, 1},
|
||||
{:unit, 1},
|
||||
{:unsigned, 0},
|
||||
{:utf8, 0},
|
||||
{:utf16, 0},
|
||||
{:utf32, 0}
|
||||
]
|
||||
|
||||
@doc """
|
||||
Returns a list of identifiers matching the given `hint`
|
||||
together with relevant information.
|
||||
|
@ -151,7 +173,10 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
match_default(ctx)
|
||||
|
||||
{:local_or_var, local_or_var} ->
|
||||
match_in_struct_fields_or_local_or_var(List.to_string(local_or_var), ctx)
|
||||
hint = List.to_string(local_or_var)
|
||||
|
||||
match_container_context(ctx.fragment, hint) ||
|
||||
match_in_struct_fields_or_local_or_var(hint, ctx)
|
||||
|
||||
{:local_arity, local} ->
|
||||
match_local(List.to_string(local), %{ctx | matcher: @exact_matcher})
|
||||
|
@ -162,6 +187,10 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
:locate -> match_local(List.to_string(local), %{ctx | matcher: @exact_matcher})
|
||||
end
|
||||
|
||||
{:operator, operator} when operator in ~w(:: -)c ->
|
||||
match_container_context(ctx.fragment, "") ||
|
||||
match_local_or_var(List.to_string(operator), ctx)
|
||||
|
||||
{:operator, operator} ->
|
||||
match_local_or_var(List.to_string(operator), ctx)
|
||||
|
||||
|
@ -297,6 +326,34 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
defp match_container_context(code, hint) do
|
||||
case container_context(code) do
|
||||
:bitstring_modifier ->
|
||||
existing = code |> String.split("::") |> List.last() |> String.split("-")
|
||||
|
||||
for {modifier, arity} <- @bitstring_modifiers,
|
||||
name = Atom.to_string(modifier),
|
||||
String.starts_with?(name, hint) and name not in existing,
|
||||
do: %{kind: :bitstring_modifier, name: modifier, arity: arity}
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
defp container_context(code) do
|
||||
case Code.Fragment.container_cursor_to_quoted(code) do
|
||||
{:ok, quoted} ->
|
||||
case Macro.path(quoted, &match?({:__cursor__, _, []}, &1)) do
|
||||
[cursor, {:"::", _, [_, cursor]}, {:<<>>, _, [_ | _]} | _] -> :bitstring_modifier
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
{:error, _} ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
defp expand_struct_fields(ctx) do
|
||||
with {:ok, quoted} <- Code.Fragment.container_cursor_to_quoted(ctx.fragment),
|
||||
{aliases, pairs} <- find_struct_fields(quoted) do
|
||||
|
|
|
@ -1158,6 +1158,38 @@ defmodule Livebook.IntellisenseTest do
|
|||
}
|
||||
] = Intellisense.get_completion_items("__EN", context)
|
||||
end
|
||||
|
||||
test "Elixir bitstring modifiers" do
|
||||
context = eval(do: nil)
|
||||
|
||||
assert [
|
||||
%{
|
||||
detail: "bitstring option",
|
||||
documentation: nil,
|
||||
insert_text: "integer",
|
||||
kind: :bitstring_option,
|
||||
label: "integer"
|
||||
}
|
||||
] = Intellisense.get_completion_items("<<a::intege", context)
|
||||
|
||||
assert [
|
||||
%{
|
||||
detail: "bitstring option",
|
||||
documentation: nil,
|
||||
insert_text: "size($0)",
|
||||
kind: :bitstring_option,
|
||||
label: "size"
|
||||
}
|
||||
] = Intellisense.get_completion_items("<<a::siz", context)
|
||||
|
||||
assert %{
|
||||
detail: "bitstring option",
|
||||
documentation: nil,
|
||||
insert_text: "integer",
|
||||
kind: :bitstring_option,
|
||||
label: "integer"
|
||||
} in Intellisense.get_completion_items("<<a::", context)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_details/3" do
|
||||
|
|
Loading…
Add table
Reference in a new issue