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)
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
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)
def get_dir_parts(path) Set.new(File.dirname(path).split(File::SEPARATOR)) end
def initialize(path, workspace_path)
def initialize(path, workspace_path) super() @workspace_path = workspace_path @path = path.delete_prefix(workspace_path) #: String end
def perform
@override
def perform find_relevant_paths end
def relevant_filename_pattern
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