Skip to content

Conversation

@myronmarston
Copy link
Contributor

Follow up to #5488.


defp to_entries(%{kind: :module, name: name}) do
defp to_entries(%{kind: kind, name: name})
when kind in [:map_key, :module, :var_name] do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please indent this as follows:

defp to_entries(%{kind: kind, name: name}) when
     kind in [:map_key, :module, :var_name] do

Same below. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josevalim is this the new preferred way of breaking up guards? leaving when at the end of the first line?

end

defp find_matched_variables(binding, var_prefix) do
for {var_name, _value} <- binding,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that variable names in bindings are atoms, they are not always atoms in bindings because of hygiene, and then use Atom.to_string/1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know -- I had no idea! Is it worth adding test coverage for this since it's a simple mistake to make? What's an example of an expression that would result in a variable name not being an atom?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any expression that defines a variable inside a quote:

iex(1)> Code.eval_quoted (quote do var = 1 end), []
{1, [{{:var, Elixir}, 1}]}

One suggestion is to define a macro inside the test module and invoke that macro on @tag previous_line: "Mod.macro".

- Format multi-line guard clauses as requested.
- Do not assume that binding keys are always atoms.
This aligns with the existing kind values. We use
`:function`, `:map_key` and `:module`, not `:fun_name`,
`:map_key_name` and `:mod_name`.
@myronmarston
Copy link
Contributor Author

@josevalim I can't get your suggestion to work. I tried this:

defmacro define_var do
  quote do: my_var_1 = 1
end

@tag previous_line: "require #{__MODULE__}; #{__MODULE__}.define_var(); my_var_2 = 2"
test "ignores quoted variables when performing variable completion" do
  assert expand('my_var') == {:yes, '_2', []}
end

The test passes (which is good) but still passes if I undo my "filter to only atom variables" fix. I added some debug printing and found that the binding is just [my_var_2: 2] -- meaning that the variable inside the macro isn't affecting the evaulator's binding at all.

Thoughts?

@josevalim
Copy link
Member

@myronmarston I will investigate.

@myronmarston
Copy link
Contributor Author

@myronmarston I will investigate.

Great, thanks.

BTW, I've got the custom import auto-completion ready to go now, too. Do you want me to push that commit to this PR so it is included or should I wait until this is merged and then open a new PR? It builds on top of this one so I can't open another PR without also including the commits from this one.

@josevalim
Copy link
Member

@myronmarston using var!(my_var_1, Elixir) when reading and writing should be enough to make the code fail. We give an integer context for other variables (truly temporary) and those are discarded from the binding.

@josevalim
Copy link
Member

josevalim commented Nov 30, 2016

Let's wait until this is merged since I think there should be nothing more blocking it.

Also, fix the way we filter out non-atom variables.
For some reason, the guard clause did not work.
@myronmarston
Copy link
Contributor Author

Thanks, the var! bit worked. However, I was surprised to discover that my guard clause in the for comprehension did not work to filter out non-atom variable names:

for {var_name, _value} when is_atom(var_name) <- binding,
# ...

Instead, I had to use a filter clause:

for {var_name, _value} <- binding,
    is_atom(var_name),
# ...

Is that expected? It certainly surprised me.

@josevalim
Copy link
Member

That's a bug. Or we should fail to compile or it should work. Please open up an issue.

@josevalim
Copy link
Member

@myronmarston fwiw, i cannot reproduce it:

iex(1)> for {k, v} when is_atom(v) <- [foo: :bar, baz: 1], do: v
[:bar]

@myronmarston
Copy link
Contributor Author

Thanks for fixing the for comprehension bug, @josevalim! Do you want me to rebase against that and revert back to using a guard clause to filter to just atoms?

@josevalim josevalim merged commit adc0169 into elixir-lang:master Dec 1, 2016
@josevalim
Copy link
Member

❤️ 💚 💙 💛 💜

myronmarston added a commit to seomoz/elixir that referenced this pull request Jun 26, 2017
- Variable name autocompletion was added in elixir-lang#5504.
- Autocompletion of imported `:only` functions was added in elixir-lang#5518.
josevalim pushed a commit that referenced this pull request Jun 26, 2017
- Variable name autocompletion was added in #5504.
- Autocompletion of imported `:only` functions was added in #5518.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants