Method: NA.match_working_dir

Defined in:
lib/na/next_action.rb

.match_working_dir(search, distance: 1, require_last: true) ⇒ Array<String>

Find a matching path using semi-fuzzy matching. Search tokens can include ! and + to negate or make required.

Parameters:

  • search (Array<Hash>)

    Search tokens to match

  • distance (Integer) (defaults to: 1)

    Allowed distance between characters

  • require_last (Boolean) (defaults to: true)

    Require regex to match last element of path

Returns:

  • (Array<String>)

    Array of matching directories/todo files



882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
# File 'lib/na/next_action.rb', line 882

def match_working_dir(search, distance: 1, require_last: true)
  file = database_path
  NA.notify("#{NA.theme[:error]}No na database found", exit_code: 1) unless File.exist?(file)

  dirs = file.read_file.split("\n")

  optional = search.filter { |s| !s[:negate] }.map { |t| t[:token] }
  required = search.filter { |s| s[:required] && !s[:negate] }.map { |t| t[:token] }
  negated = search.filter { |s| s[:negate] }.map { |t| t[:token] }

  optional.push('*') if optional.none? && required.none? && negated.any?
  if optional == negated
    required = ['*']
    optional = ['*']
  end

  NA.notify("Optional directory regex: {x}#{optional.map { |t| t.dir_to_rx(distance: distance) }}", debug: true)
  NA.notify("Required directory regex: {x}#{required.map { |t| t.dir_to_rx(distance: distance) }}", debug: true)
  NA.notify("Negated directory regex: {x}#{negated.map do |t|
    t.dir_to_rx(distance: distance, require_last: false)
  end}", debug: true)

  if require_last
    dirs.delete_if do |d|
      !d.sub(/\.#{NA.extension}$/, '')
        .dir_matches?(any: optional, all: required, none: negated, require_last: true, distance: distance)
    end
  else
    dirs.delete_if do |d|
      !d.sub(/\.#{NA.extension}$/, '')
        .dir_matches?(any: optional, all: required, none: negated, distance: 2, require_last: false)
    end
  end

  dirs = dirs.sort_by { |d| File.basename(d) }.uniq

  dirs = find_exact_dir(dirs, search) unless optional == ['*']

  if dirs.empty? && require_last
    NA.notify("#{NA.theme[:warning]}No matches, loosening search", debug: true)
    match_working_dir(search, distance: 2, require_last: false)
  else
    NA.notify("Matched files: {x}#{dirs.join(', ')}", debug: true)
    dirs
  end
end