diff --git a/lib/elixir_sense/core/normalized/code/cursor_context.ex b/lib/elixir_sense/core/normalized/code/cursor_context.ex new file mode 100644 index 00000000..d81f3dee --- /dev/null +++ b/lib/elixir_sense/core/normalized/code/cursor_context.ex @@ -0,0 +1,16 @@ +defmodule ElixirSense.Core.Normalized.Code.CursorContext do + @moduledoc false + + def cursor_context(string, opts \\ []) + + # credo:disable-for-lines:10 + def cursor_context(binary, opts) do + cond do + Version.match?(System.version(), ">= 1.13.0") -> + apply(Code.Fragment, :cursor_context, [binary, opts]) + + true -> + apply(Code, :cursor_context, [binary, opts]) + end + end +end diff --git a/lib/elixir_sense/core/normalized/tokenizer.ex b/lib/elixir_sense/core/normalized/tokenizer.ex index 34340917..5becfaf1 100644 --- a/lib/elixir_sense/core/normalized/tokenizer.ex +++ b/lib/elixir_sense/core/normalized/tokenizer.ex @@ -14,10 +14,18 @@ defmodule ElixirSense.Core.Normalized.Tokenizer do defp do_tokenize_1_7(prefix_charlist) do case :elixir_tokenizer.tokenize(prefix_charlist, 1, []) do + # Elixir < 1.13 + {:ok, tokens} -> + Enum.reverse(tokens) + # Elixir >= 1.13 {:ok, _line, _column, _warning, tokens} -> Enum.reverse(tokens) + # Elixir < 1.13 + {:error, {_line, _column, _error_prefix, _token}, _rest, sofar} -> + sofar + # Elixir >= 1.13 {:error, _, _, _, sofar} -> sofar diff --git a/lib/elixir_sense/providers/suggestion/complete.ex b/lib/elixir_sense/providers/suggestion/complete.ex index e0d61fc8..6dbc5df7 100644 --- a/lib/elixir_sense/providers/suggestion/complete.ex +++ b/lib/elixir_sense/providers/suggestion/complete.ex @@ -73,7 +73,14 @@ defmodule ElixirSense.Providers.Suggestion.Complete do end def do_expand(code, %State.Env{} = env, %Metadata{} = metadata, cursor_position, opts \\ []) do - case Code.Fragment.cursor_context(code) do + # TODO remove when we require elixir 1.13 + only_structs = + case code do + [?% | _] -> true + _ -> false + end + + case NormalizedCode.CursorContext.cursor_context(code) do {:alias, hint} when is_list(hint) -> expand_aliases(List.to_string(hint), env, metadata, cursor_position, false, opts) @@ -84,10 +91,10 @@ defmodule ElixirSense.Providers.Suggestion.Complete do expand_erlang_modules(List.to_string(unquoted_atom), env, metadata) {:dot, path, hint} -> - expand_dot(path, List.to_string(hint), false, env, metadata, cursor_position, false, opts) + expand_dot(path, List.to_string(hint), false, env, metadata, cursor_position, only_structs, opts) {:dot_arity, path, hint} -> - expand_dot(path, List.to_string(hint), true, env, metadata, cursor_position, false, opts) + expand_dot(path, List.to_string(hint), true, env, metadata, cursor_position, only_structs, opts) {:dot_call, _path, _hint} -> # no need to expand signatures here, we have signatures provider @@ -98,7 +105,8 @@ defmodule ElixirSense.Providers.Suggestion.Complete do :expr -> # IEx calls expand_local_or_var("", env) - # we choose to return more and handle some special cases + # we choose to retun more and handle some special cases + # TODO expand_expr(env) after we require elixir 1.13 case code do [?^] -> expand_var("", env, metadata) [?%] -> expand_aliases("", env, metadata, cursor_position, true, opts) @@ -121,6 +129,7 @@ defmodule ElixirSense.Providers.Suggestion.Complete do # to provide signatures and falls back to expand_local_or_var expand_expr(env, metadata, cursor_position, opts) + # elixir >= 1.13 {:operator, operator} -> case operator do [?^] -> expand_var("", env, metadata) @@ -128,20 +137,25 @@ defmodule ElixirSense.Providers.Suggestion.Complete do _ -> expand_local(List.to_string(operator), false, env, metadata, cursor_position) end + # elixir >= 1.13 {:operator_arity, operator} -> expand_local(List.to_string(operator), true, env, metadata, cursor_position) + # elixir >= 1.13 {:operator_call, _operator} -> expand_local_or_var("", env, metadata, cursor_position) + # elixir >= 1.13 {:sigil, []} -> expand_sigil(env, metadata, cursor_position) + # elixir >= 1.13 {:sigil, [_]} -> # {:yes, [], ~w|" """ ' ''' \( / < [ { \||c} # we choose to not provide sigil chars no() + # elixir >= 1.13 {:struct, struct} when is_list(struct) -> expand_aliases(List.to_string(struct), env, metadata, cursor_position, true, opts)