Skip to content

Commit 9b5c8c4

Browse files
committed
fuzzy matching map fields and aliases
1 parent 8e3c1bc commit 9b5c8c4

File tree

4 files changed

+26
-33
lines changed

4 files changed

+26
-33
lines changed

lib/elixir_sense/providers/suggestion/complete.ex

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ defmodule ElixirSense.Providers.Suggestion.Complete do
376376
defp match_aliases(hint, env) do
377377
for {alias, _mod} <- env.aliases,
378378
[name] = Module.split(alias),
379-
String.starts_with?(name, hint) do
379+
Matcher.match?(name, hint) do
380380
%{kind: :module, type: :alias, name: name, desc: {"", %{}}, subtype: nil}
381381
end
382382
end
@@ -433,12 +433,20 @@ defmodule ElixirSense.Providers.Suggestion.Complete do
433433
end
434434

435435
defp match_modules(hint, root, env) do
436+
hint_parts = hint |> String.split(".")
437+
hint_parts_length = length(hint_parts)
438+
[hint_suffix | hint_prefix] = hint_parts |> Enum.reverse()
439+
436440
root
437441
|> get_modules(env)
438442
|> Enum.sort()
439443
|> Enum.dedup()
440-
|> Enum.drop_while(&(not String.starts_with?(&1, hint)))
441-
|> Enum.take_while(&String.starts_with?(&1, hint))
444+
|> Enum.filter(fn mod ->
445+
[mod_suffix | mod_prefix] =
446+
mod |> String.split(".") |> Enum.take(hint_parts_length) |> Enum.reverse()
447+
448+
hint_prefix == mod_prefix and Matcher.match?(mod_suffix, hint_suffix)
449+
end)
442450
end
443451

444452
defp get_modules(true, env) do
@@ -700,7 +708,7 @@ defmodule ElixirSense.Providers.Suggestion.Complete do
700708
defp match_map_fields(fields, hint, type) do
701709
for {key, value} when is_atom(key) <- fields,
702710
key = Atom.to_string(key),
703-
String.starts_with?(key, hint) do
711+
Matcher.match?(key, hint) do
704712
value_is_map =
705713
case value do
706714
{:map, _, _} -> true

test/elixir_sense/providers/suggestion/complete_test.exs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,18 @@ defmodule ElixirSense.Providers.Suggestion.CompleteTest do
176176
%{name: "Stream", subtype: :struct, type: :module},
177177
%{name: "String", subtype: nil, type: :module},
178178
%{name: "StringIO", subtype: nil, type: :module}
179-
] = expand('Str')
179+
] = expand('Str') |> Enum.filter(&(&1.name |> String.starts_with?("Str")))
180180

181181
assert [
182182
%{name: "Macro"},
183183
%{name: "Map"},
184184
%{name: "MapSet"},
185185
%{name: "MatchError"}
186-
] = expand('Ma')
186+
] = expand('Ma') |> Enum.filter(&(&1.name |> String.starts_with?("Ma")))
187+
188+
assert [%{name: "Dict"}] =
189+
expand('Dic') |> Enum.filter(&(&1.name |> String.starts_with?("Dic")))
187190

188-
assert [%{name: "Dict"}] = expand('Dic')
189191
assert suggestions = expand('Ex')
190192
assert Enum.any?(suggestions, &(&1.name == "ExUnit"))
191193
assert Enum.any?(suggestions, &(&1.name == "Exception"))
@@ -900,7 +902,7 @@ defmodule ElixirSense.Providers.Suggestion.CompleteTest do
900902
}
901903
}
902904

903-
assert [%{name: "Some", type: :module}] = expand('So', env)
905+
assert [%{name: "Some", type: :module}] = expand('Som', env)
904906
assert [%{name: "OtherModule", type: :module}] = expand('Some.', env)
905907
assert [%{name: "MyAlias", type: :module}] = expand('MyA', env)
906908
end
@@ -1419,7 +1421,7 @@ defmodule ElixirSense.Providers.Suggestion.CompleteTest do
14191421
subtype: nil,
14201422
summary: "This module contains functions to manipulate files."
14211423
}
1422-
] = expand('Fi')
1424+
] = expand('Fi') |> Enum.filter(&(&1.name == "File"))
14231425
end
14241426

14251427
test "complete only struct modules after %" do

test/elixir_sense/providers/suggestion_test.exs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -75,26 +75,6 @@ defmodule ElixirSense.Providers.SuggestionTest do
7575
}
7676
end
7777

78-
test "return completion candidates for 'Str'" do
79-
assert Suggestion.find("ElixirSenseExample.ModuleWithDo", @env, %Metadata{}, @cursor_context) ==
80-
[
81-
%{
82-
name: "ModuleWithDocFalse",
83-
subtype: nil,
84-
summary: "",
85-
type: :module,
86-
metadata: %{}
87-
},
88-
%{
89-
name: "ModuleWithDocs",
90-
subtype: :behaviour,
91-
summary: "An example module\n",
92-
type: :module,
93-
metadata: %{since: "1.2.3"}
94-
}
95-
]
96-
end
97-
9878
test "return completion candidates for 'List.del'" do
9979
assert [
10080
%{

test/elixir_sense/suggestions_test.exs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ defmodule ElixirSense.SuggestionsTest do
309309
summary: "An example module\n",
310310
type: :module,
311311
metadata: %{since: "1.2.3"}
312-
}
312+
},
313+
%{metadata: %{}, name: "ModuleWithNoDocs", subtype: nil, summary: "", type: :module}
313314
]
314315
end
315316

@@ -1538,7 +1539,7 @@ defmodule ElixirSense.SuggestionsTest do
15381539
assert [
15391540
%{label: ~s(@typedoc """""")},
15401541
%{label: "@typedoc false"}
1541-
] = list |> Enum.filter(& &1.type == :generic and &1.kind == :snippet)
1542+
] = list |> Enum.filter(&(&1.type == :generic and &1.kind == :snippet))
15421543
end
15431544

15441545
test "functions defined in the module" do
@@ -1781,7 +1782,9 @@ defmodule ElixirSense.SuggestionsTest do
17811782
name: "SmodO",
17821783
type: :module
17831784
}
1784-
] = ElixirSense.suggestions(buffer, 9, 18)
1785+
] =
1786+
ElixirSense.suggestions(buffer, 9, 18)
1787+
|> Enum.filter(&(&1.name |> String.starts_with?("Smo")))
17851788

17861789
assert [
17871790
%{
@@ -2588,7 +2591,7 @@ defmodule ElixirSense.SuggestionsTest do
25882591
%{name: "Stream"},
25892592
%{name: "String"},
25902593
%{name: "StringIO"}
2591-
] = list
2594+
] = list |> Enum.filter(&(&1.name |> String.starts_with?("Str")))
25922595
end
25932596

25942597
test "suggest modules to alias with __MODULE__" do

0 commit comments

Comments
 (0)