class RubyLsp::Requests::GoToRelevantFile

Currently, it supports source code file <> test file navigation.
that navigates to the relevant file for the current document.
request](microsoft.github.io/language-server-protocol/specification#requestMessage)
GoTo Relevant File is a custom [LSP

def find_most_similar_with_jaccard(candidates)

: (Array[String] candidates) -> Array[String]
would be the parts of the path separated by path divider.)
it by the size of union between two sets (in our case the elements in each set
The main idea of this algorithm is to take the size of interaction and divide
Ref: https://en.wikipedia.org/wiki/Jaccard_index
input path and the candidate relevant file paths.
Using the Jaccard algorithm to determine the similarity between the
def find_most_similar_with_jaccard(candidates)
  dirs = get_dir_parts(@path)
  _, results = candidates
    .group_by do |other_path|
      other_dirs = get_dir_parts(other_path)
      # Similarity score between the two directories
      (dirs & other_dirs).size.to_f / (dirs | other_dirs).size
    end
    .max_by(&:first)
  results || []
end

def find_relevant_paths

: -> Array[String]
def find_relevant_paths
  candidate_paths = Dir.glob(File.join("**", relevant_filename_pattern))
  return [] if candidate_paths.empty?
  find_most_similar_with_jaccard(candidate_paths).map { File.join(@workspace_path, _1) }
end

def get_dir_parts(path)

: (String path) -> Set[String]
def get_dir_parts(path)
  Set.new(File.dirname(path).split(File::SEPARATOR))
end

def initialize(path, workspace_path)

: (String path, String workspace_path) -> void
def initialize(path, workspace_path)
  super()
  @workspace_path = workspace_path
  @path = path.delete_prefix(workspace_path) #: String
end

def perform

: -> Array[String]
@override
def perform
  find_relevant_paths
end

def relevant_filename_pattern

: -> String
def relevant_filename_pattern
  input_basename = File.basename(@path, File.extname(@path))
  relevant_basename_pattern =
    if input_basename.match?(TEST_PATTERN)
      input_basename.gsub(TEST_PATTERN, "")
    else
      "{{#{TEST_PREFIX_GLOB}}#{input_basename},#{input_basename}{#{TEST_SUFFIX_GLOB}}}"
    end
  "#{relevant_basename_pattern}#{File.extname(@path)}"
end