#!/usr/bin/env ruby require 'utils' include Utils require 'tins/xt' include Tins::GO def edit_files(*paths, pick: false, wait: true) editor = Utils::Editor.new if pick if paths.size > 1 path = complete(prompt: 'Pick? ') do |p| paths.grep /#{p}/ end else path = paths.first end editor.edit(path.strip) else editor.wait = wait editor.edit(*paths) end end def usage puts <<-EOT Usage: #{File.basename($0)} [OPTS] [PATTERN] [PATHS] PATTERN is a pattern expression which is find the files. PATHS are the directory and file paths that are searched. Options are -pX interpret PATTERN argument as X=r for regexp or X=f for fuzzy -r reset the search index -c disable color output -e open the matching files with edit command -E pick one file to edit -a CSET use only character set CSET from PATTERN -iX use case insensitive matches with X=y (default) or not with X=n -I SUFFIX only include files with suffix SUFFIX during finding -d match also directories -D list all search leaf directories -v be verbose -n NUMBER the first NUMBER of matches is returned -s search by interactively inputting PATTERN -h display this help Version is #{File.basename($0)} #{Utils::VERSION}. EOT exit 1 end args = go 'n:I:i:a:p:creEvdsDh' args[?h] and usage Term::ANSIColor.coloring = (STDIN.tty? && ENV['TERM'] !~ /dumb/) && !args[?c] STDOUT.sync = true config = Utils::ConfigFile.new config.configure_from_paths args[?b] ||= config.discover.binary args[?n] ||= config.discover.max_matches if args[?s] pattern = '' else pattern = ARGV.shift || '' end roots = (ARGV.empty? ? [ Dir.pwd ] : ARGV).map { |f| File.expand_path(f) } finder = -> * { Finder.new( :pattern => pattern, :args => args, :roots => roots, :config => config ) } case when args[?s] f = nil pattern = pattern.dup args[?n] = Term::ANSIColor.terminal_lines - 1 path = nil found = Utils::SearchUI.new( query: -> answer, selector { pattern.replace answer f = finder.() f.search.output.each_with_index.map { |l, i| (i == selector ? '> ' : ' ') + l }.join(?\n) }, found: -> answer, selector { f and path = f.paths[selector] }, output: STDERR ).start if found if args[?e] edit_files path, wait: false else found and puts path end exit 0 else exit 1 end when args[?E] edit_files *finder.().paths, pick: true when args[?e] edit_files *finder.().search.paths when args[?D] args[?d] = true paths = finder.().load_paths.select { |p| File.directory?(p) }.reverse leaf_dirs = [] until paths.empty? path = paths.shift unless leaf_dirs.any? { |ld| ld.start_with?(path) } leaf_dirs.push path end end puts leaf_dirs when pattern.empty? && args[?r] finder.() exit when pattern.empty? usage else puts finder.().search.output end