From 86e1eb36e7acb431743db0ac6c79282746cf7435 Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Thu, 18 Apr 2024 14:02:53 -0700 Subject: [PATCH 1/3] Included non-deps symbols in fuzzy matcher I noticed that the fuzzy matcher wouldn't match any unit tests. This is because their application is nil, as they're scripts. This change checks for nil applications, and if it finds one, only excludes the mapped entry if the path looks like it comes from a dependencies directory. Note, the deps directory name is hard coded. I originally queried the project for the deps directory name, but this would include dependencies in the projects directory, which was quite annoying, hence the hard-coding. --- .../lexical/remote_control/search/fuzzy.ex | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex b/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex index 7fa6fca18..7b311f323 100644 --- a/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex +++ b/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex @@ -359,8 +359,26 @@ defmodule Lexical.RemoteControl.Search.Fuzzy do names end - fn mapped(application: app, subtype: subtype) -> - subtype == :definition and MapSet.member?(app_names, app) + # we do the path thing to ensure that + # we get a valid OS-specifc path component + # so we can do `String.contains?` on a path + deps_part = + [" ", "deps", " "] + |> Path.join() + |> String.trim() + + fn + mapped(application: nil, subtype: :definition, grouping_key: path) -> + # if we don't have an app name, just make sure we're not + # in what looks like a deps directory + + not String.contains?(path, deps_part) + + mapped(application: app, subtype: :definition) -> + MapSet.member?(app_names, app) + + _ -> + false end end end From 91eabf6f19531d34c27ae7f9e1d4dd7ed9abbf57 Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Mon, 22 Apr 2024 15:03:38 -0700 Subject: [PATCH 2/3] Changed how we detect dependencies Dependencies are now detected via seeing if the path is in our deps directory or one of our sub-project's dependencies. --- .../lexical/remote_control/search/fuzzy.ex | 75 +++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex b/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex index 7b311f323..347118f50 100644 --- a/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex +++ b/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex @@ -11,6 +11,7 @@ defmodule Lexical.RemoteControl.Search.Fuzzy do returned. """ + alias Lexical.Project alias Lexical.RemoteControl alias Lexical.RemoteControl.Search.Fuzzy.Scorer alias Lexical.RemoteControl.Search.Indexer.Entry @@ -336,49 +337,63 @@ defmodule Lexical.RemoteControl.Search.Fuzzy do end defp build_filter_fn do - mix_app_names = fn -> - applications = - if Mix.Project.umbrella?() do - Map.keys(Mix.Project.apps_paths()) - else - List.wrap(Mix.Project.config()[:app]) - end - - MapSet.new(applications) - end - - app_names = + deps_directories = if Mix.Project.get() do - mix_app_names.() + deps_roots() else - {:ok, names} = + {:ok, deps_roots} = RemoteControl.Mix.in_project(fn _ -> - mix_app_names.() + deps_roots() end) - names + deps_roots end - # we do the path thing to ensure that - # we get a valid OS-specifc path component - # so we can do `String.contains?` on a path - deps_part = - [" ", "deps", " "] - |> Path.join() - |> String.trim() - fn - mapped(application: nil, subtype: :definition, grouping_key: path) -> + mapped(subtype: :definition, grouping_key: path) -> # if we don't have an app name, just make sure we're not # in what looks like a deps directory - - not String.contains?(path, deps_part) - - mapped(application: app, subtype: :definition) -> - MapSet.member?(app_names, app) + not Enum.any?(deps_directories, &String.starts_with?(path, &1)) _ -> false end end + + defp deps_roots do + deps_roots(RemoteControl.get_project()) + end + + defp deps_roots(%Project{mix_project?: true} = project) do + # Note: This function assumes that the deps directories for all + # found projects is `deps`. Projects may override this directory + # and lexical won't understand this. This was done because loading + # each sub-project is expensive and changes our global directory. + + root_deps_path = Mix.Project.deps_path() + {root_deps_path, Project.mix_exs_path(project)} + + [Project.root_path(project), "**", "mix.exs"] + |> Path.join() + |> Path.wildcard() + |> Enum.map(&Path.absname/1) + |> Enum.reduce([], fn mix_exs_path, deps_paths -> + deps_dir = + mix_exs_path + |> Path.dirname() + |> Path.join("deps") + + if File.exists?(deps_dir) do + [deps_dir | deps_paths] + else + deps_paths + end + end) + |> Enum.reverse() + |> Enum.uniq() + end + + defp deps_roots(_) do + [] + end end From 1a9f403bd9f1928d33ee93292b4417fe8b9b129f Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Tue, 23 Apr 2024 07:56:44 -0700 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Zach Allaun --- .../lexical/remote_control/search/fuzzy.ex | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex b/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex index 347118f50..1deb49e01 100644 --- a/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex +++ b/apps/remote_control/lib/lexical/remote_control/search/fuzzy.ex @@ -370,27 +370,16 @@ defmodule Lexical.RemoteControl.Search.Fuzzy do # and lexical won't understand this. This was done because loading # each sub-project is expensive and changes our global directory. - root_deps_path = Mix.Project.deps_path() - {root_deps_path, Project.mix_exs_path(project)} - [Project.root_path(project), "**", "mix.exs"] |> Path.join() |> Path.wildcard() - |> Enum.map(&Path.absname/1) - |> Enum.reduce([], fn mix_exs_path, deps_paths -> - deps_dir = - mix_exs_path - |> Path.dirname() - |> Path.join("deps") - - if File.exists?(deps_dir) do - [deps_dir | deps_paths] - else - deps_paths - end + |> Enum.map(fn relative_mix_path -> + relative_mix_path + |> Path.absname() + |> Path.dirname() + |> Path.join("deps") end) - |> Enum.reverse() - |> Enum.uniq() + |> Enum.filter(&File.exists?/1) end defp deps_roots(_) do