Skip to content

Commit 706c498

Browse files
committed
pass cursor position to binding
1 parent 0e2bdbd commit 706c498

File tree

16 files changed

+134
-61
lines changed

16 files changed

+134
-61
lines changed

lib/elixir_sense/core/binding.ex

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ defmodule ElixirSense.Core.Binding do
1919
requires: [],
2020
specs: %{},
2121
types: %{},
22-
mods_funs_to_positions: %{}
22+
mods_funs_to_positions: %{},
23+
cursor_position: {1, 1}
2324

24-
def from_env(%State.Env{} = env, %ElixirSense.Core.Metadata{} = metadata) do
25+
def from_env(%State.Env{} = env, %ElixirSense.Core.Metadata{} = metadata, cursor_position) do
2526
%Binding{
2627
vars: env.vars,
2728
attributes: env.attributes,
@@ -33,7 +34,8 @@ defmodule ElixirSense.Core.Binding do
3334
module: env.module,
3435
function: env.function,
3536
types: metadata.types,
36-
mods_funs_to_positions: metadata.mods_funs_to_positions
37+
mods_funs_to_positions: metadata.mods_funs_to_positions,
38+
cursor_position: cursor_position
3739
}
3840
end
3941

@@ -99,8 +101,7 @@ defmodule ElixirSense.Core.Binding do
99101
# no variable found - treat as a local call
100102
# this can happen if no parens call is missclassed as variable e.g. by
101103
# Code.Fragment APIs
102-
# TODO pass cursor position
103-
{:local_call, variable, {1, 1}, []}
104+
{:local_call, variable, env.cursor_position, []}
104105

105106
%State.VarInfo{type: type} ->
106107
type

lib/elixir_sense/core/type_inference.ex

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ defmodule ElixirSense.Core.TypeInference do
3030
end
3131

3232
# remote call
33-
def type_of({{:., _, [target, fun]}, meta, args}, context)
33+
def type_of({{:., _, [target, fun]}, _meta, args}, context)
3434
when is_atom(fun) and is_list(args) do
3535
target = type_of(target, context)
36-
line = Keyword.get(meta, :line, 1)
37-
column = Keyword.get(meta, :column, 1)
3836
{:call, target, fun, Enum.map(args, &type_of(&1, context))}
3937
end
4038

lib/elixir_sense/providers/completion/completion_engine.ex

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do
255255
) do
256256
filter = struct_module_filter(only_structs, env, metadata)
257257

258-
case expand_dot_path(path, env, metadata) do
258+
case expand_dot_path(path, env, metadata, cursor_position) do
259259
{:ok, {:atom, mod}} when hint == "" ->
260260
expand_aliases(
261261
mod,
@@ -284,23 +284,38 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do
284284
end
285285

286286
# elixir >= 1.14
287-
defp expand_dot_path({:var, ~c"__MODULE__"}, %State.Env{} = env, %Metadata{} = _metadata) do
287+
defp expand_dot_path(
288+
{:var, ~c"__MODULE__"},
289+
%State.Env{} = env,
290+
%Metadata{} = _metadata,
291+
_cursor_position
292+
) do
288293
if env.module != nil and Introspection.elixir_module?(env.module) do
289294
{:ok, {:atom, env.module}}
290295
else
291296
:error
292297
end
293298
end
294299

295-
defp expand_dot_path({:var, var}, %State.Env{} = env, %Metadata{} = metadata) do
296-
value_from_binding({:variable, List.to_atom(var), :any}, env, metadata)
300+
defp expand_dot_path({:var, var}, %State.Env{} = env, %Metadata{} = metadata, cursor_position) do
301+
value_from_binding({:variable, List.to_atom(var), :any}, env, metadata, cursor_position)
297302
end
298303

299-
defp expand_dot_path({:module_attribute, attribute}, %State.Env{} = env, %Metadata{} = metadata) do
300-
value_from_binding({:attribute, List.to_atom(attribute)}, env, metadata)
304+
defp expand_dot_path(
305+
{:module_attribute, attribute},
306+
%State.Env{} = env,
307+
%Metadata{} = metadata,
308+
cursor_position
309+
) do
310+
value_from_binding({:attribute, List.to_atom(attribute)}, env, metadata, cursor_position)
301311
end
302312

303-
defp expand_dot_path({:alias, hint}, %State.Env{} = env, %Metadata{} = metadata) do
313+
defp expand_dot_path(
314+
{:alias, hint},
315+
%State.Env{} = env,
316+
%Metadata{} = metadata,
317+
_cursor_position
318+
) do
304319
alias = hint |> List.to_string() |> String.split(".") |> value_from_alias(env, metadata)
305320

306321
case alias do
@@ -313,7 +328,8 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do
313328
defp expand_dot_path(
314329
{:alias, {:local_or_var, var}, hint},
315330
%State.Env{} = env,
316-
%Metadata{} = metadata
331+
%Metadata{} = metadata,
332+
_cursor_position
317333
) do
318334
case var do
319335
~c"__MODULE__" ->
@@ -333,9 +349,10 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do
333349
defp expand_dot_path(
334350
{:alias, {:module_attribute, attribute}, hint},
335351
%State.Env{} = env,
336-
%Metadata{} = metadata
352+
%Metadata{} = metadata,
353+
cursor_position
337354
) do
338-
case value_from_binding({:attribute, List.to_atom(attribute)}, env, metadata) do
355+
case value_from_binding({:attribute, List.to_atom(attribute)}, env, metadata, cursor_position) do
339356
{:ok, {:atom, atom}} ->
340357
if Introspection.elixir_module?(atom) do
341358
alias_suffix = hint |> List.to_string() |> String.split(".")
@@ -354,26 +371,46 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do
354371
end
355372
end
356373

357-
defp expand_dot_path({:alias, _, _hint}, %State.Env{} = _env, %Metadata{} = _metadata) do
374+
defp expand_dot_path(
375+
{:alias, _, _hint},
376+
%State.Env{} = _env,
377+
%Metadata{} = _metadata,
378+
_cursor_position
379+
) do
358380
:error
359381
end
360382

361-
defp expand_dot_path({:unquoted_atom, var}, %State.Env{} = _env, %Metadata{} = _metadata) do
383+
defp expand_dot_path(
384+
{:unquoted_atom, var},
385+
%State.Env{} = _env,
386+
%Metadata{} = _metadata,
387+
_cursor_position
388+
) do
362389
{:ok, {:atom, List.to_atom(var)}}
363390
end
364391

365-
defp expand_dot_path({:dot, parent, call}, %State.Env{} = env, %Metadata{} = metadata) do
366-
case expand_dot_path(parent, env, metadata) do
392+
defp expand_dot_path(
393+
{:dot, parent, call},
394+
%State.Env{} = env,
395+
%Metadata{} = metadata,
396+
cursor_position
397+
) do
398+
case expand_dot_path(parent, env, metadata, cursor_position) do
367399
{:ok, expanded} ->
368-
value_from_binding({:call, expanded, List.to_atom(call), []}, env, metadata)
400+
value_from_binding(
401+
{:call, expanded, List.to_atom(call), []},
402+
env,
403+
metadata,
404+
cursor_position
405+
)
369406

370407
:error ->
371408
:error
372409
end
373410
end
374411

375412
# elixir >= 1.15
376-
defp expand_dot_path(:expr, %State.Env{} = _env, %Metadata{} = _metadata) do
413+
defp expand_dot_path(:expr, %State.Env{} = _env, %Metadata{} = _metadata, _cursor_position) do
377414
# TODO expand expression
378415
:error
379416
end
@@ -672,7 +709,7 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do
672709
cursor_position,
673710
only_structs
674711
) do
675-
case value_from_binding({:attribute, List.to_atom(attribute)}, env, metadata) do
712+
case value_from_binding({:attribute, List.to_atom(attribute)}, env, metadata, cursor_position) do
676713
{:ok, {:atom, atom}} ->
677714
if Introspection.elixir_module?(atom) do
678715
expand_aliases("#{atom}.#{hint}", env, metadata, cursor_position, only_structs, [])
@@ -1503,9 +1540,14 @@ defmodule ElixirSense.Providers.Completion.CompletionEngine do
15031540
end
15041541
end
15051542

1506-
defp value_from_binding(binding_ast, %State.Env{} = env, %Metadata{} = metadata) do
1543+
defp value_from_binding(
1544+
binding_ast,
1545+
%State.Env{} = env,
1546+
%Metadata{} = metadata,
1547+
cursor_position
1548+
) do
15071549
case Binding.expand(
1508-
Binding.from_env(env, metadata),
1550+
Binding.from_env(env, metadata, cursor_position),
15091551
binding_ast
15101552
) do
15111553
:none -> :error

lib/elixir_sense/providers/completion/generic_reducer.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ defmodule ElixirSense.Providers.Completion.GenericReducer do
3636
module_store: acc.context.module_store
3737
}
3838

39-
case Util.func_call_chain(text_before, env, buffer_metadata) do
39+
case Util.func_call_chain(text_before, env, buffer_metadata, cursor_context.cursor_position) do
4040
[func_call | _] = chain ->
4141
if function_exported?(reducer, :suggestions, 4) do
4242
try do

lib/elixir_sense/providers/completion/reducers/params.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule ElixirSense.Providers.Completion.Reducers.Params do
2121
def add_options(hint, env, buffer_metadata, cursor_context, acc) do
2222
prefix = cursor_context.text_before
2323

24-
binding_env = Binding.from_env(env, buffer_metadata)
24+
binding_env = Binding.from_env(env, buffer_metadata, cursor_context.cursor_position)
2525

2626
%Metadata{mods_funs_to_positions: mods_funs, types: metadata_types} = buffer_metadata
2727

lib/elixir_sense/providers/completion/reducers/record.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ defmodule ElixirSense.Providers.Completion.Reducers.Record do
5555
} = metadata,
5656
cursor_position
5757
) do
58-
binding_env = ElixirSense.Core.Binding.from_env(env, metadata)
58+
binding_env = ElixirSense.Core.Binding.from_env(env, metadata, cursor_position)
5959

6060
# check if we are inside local or remote call arguments and parameter is 0, 1 or 2
6161
# record fields can specified on 0, 1 and 2 position in the argument list

lib/elixir_sense/providers/completion/reducers/struct.ex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ defmodule ElixirSense.Providers.Completion.Reducers.Struct do
2323
def add_fields(hint, env, buffer_metadata, context, acc) do
2424
text_before = context.text_before
2525

26-
case find_struct_fields(hint, text_before, env, buffer_metadata) do
26+
case find_struct_fields(hint, text_before, env, buffer_metadata, context.cursor_position) do
2727
{[], _} ->
2828
{:cont, acc}
2929

@@ -51,9 +51,10 @@ defmodule ElixirSense.Providers.Completion.Reducers.Struct do
5151
module: module,
5252
aliases: aliases
5353
} = env,
54-
%Metadata{} = buffer_metadata
54+
%Metadata{} = buffer_metadata,
55+
cursor_position
5556
) do
56-
binding_env = ElixirSense.Core.Binding.from_env(env, buffer_metadata)
57+
binding_env = ElixirSense.Core.Binding.from_env(env, buffer_metadata, cursor_position)
5758

5859
case Source.which_struct(text_before, module) do
5960
{type, fields_so_far, elixir_prefix, var} ->

lib/elixir_sense/providers/completion/reducers/type_specs.ex

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ defmodule ElixirSense.Providers.Completion.Reducers.TypeSpecs do
2626
"""
2727

2828
# We only list type specs when inside typespec scope
29-
def add_types(hint, env, file_metadata, %{at_module_body?: _}, acc) do
29+
def add_types(
30+
hint,
31+
env,
32+
file_metadata,
33+
%{at_module_body?: _, cursor_position: cursor_position},
34+
acc
35+
) do
3036
if match?({_, _}, env.typespec) do
3137
%State.Env{
3238
aliases: aliases,
@@ -35,7 +41,7 @@ defmodule ElixirSense.Providers.Completion.Reducers.TypeSpecs do
3541

3642
%Metadata{mods_funs_to_positions: mods_funs, types: metadata_types} = file_metadata
3743

38-
binding_env = Binding.from_env(env, file_metadata)
44+
binding_env = Binding.from_env(env, file_metadata, cursor_position)
3945

4046
{mod, hint} =
4147
hint

lib/elixir_sense/providers/definition/locator.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ defmodule ElixirSense.Providers.Definition.Locator do
5757
} = env,
5858
metadata
5959
) do
60-
binding_env = Binding.from_env(env, metadata)
60+
binding_env = Binding.from_env(env, metadata, context.begin)
6161

6262
type = SurroundContext.to_binding(context.context, module)
6363

lib/elixir_sense/providers/hover/docs.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ defmodule ElixirSense.Providers.Hover.Docs do
100100
} = env,
101101
metadata
102102
) do
103-
binding_env = Binding.from_env(env, metadata)
103+
binding_env = Binding.from_env(env, metadata, context.begin)
104104

105105
type = SurroundContext.to_binding(context.context, module)
106106

0 commit comments

Comments
 (0)