class Milkode::FindGrep

Attributes

documents[R]

Public Class Methods

file2lines(file, kcode) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 388
def self.file2lines(file, kcode)
  data = file.read
  
  unless Milkode::Util.ruby19?
    if (kcode != Kconv::NOCONV)
      file_kcode = Kconv::guess(data)

      if (file_kcode != kcode)
        # puts "encode!! #{fpath} : #{kcode} <- #{file_kcode}"
        data = data.kconv(kcode, file_kcode)
      end
    end
  else
    # @memo ファイルエンコーディングに相違が起きている可能性があるため対策
    #       本当はファイルを開く時にエンコーディングを指定するのが正しい

    # 方法1 : 強制的にバイナリ化
    # data.force_encoding("Binary")
    # data = data.kconv(kcode)
    
    # 方法2 : 入力エンコーディングを強制的に指定
    data = data.kconv(kcode, Kconv::guess(data))
  end

  data = data.split($/)
end
new(patterns, option) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 57
def initialize(patterns, option)
  @patterns       = patterns
  @option         = option
  @patternRegexps = strs2regs(patterns)
  @subRegexps     = strs2regs(option.patternsNot)
  @orRegexps      = strs2regs(option.patternsOr)
  @filePatterns   = (!@option.dbFile) ? strs2regs_simple(option.filePatterns) : []
  @ignoreFiles    = strs2regs_simple(option.ignoreFiles)
  @ignoreDirs     = strs2regs_simple(option.ignoreDirs)
  @result         = Result.new(option.directory)
  open_database       if @option.dbFile
  require 'termcolor' if @option.colorHighlight
end

Public Instance Methods

convert_path(path) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 445
def convert_path(path)
 unless @option.expand_path
   Milkode::Util.relative_path(path, Dir.pwd).to_s
 else
   path
 end
end
first_condition(match_datas, sub_matchs, or_matchs) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 437
def first_condition(match_datas, sub_matchs, or_matchs)
  unless match_datas.empty?
    match_datas[0]
  else
    or_matchs[0]
  end
end
getTextLineno(path, no) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 196
def getTextLineno(path, no)
  index = no - 1

  open(path, "r") do |file|
    lines = file2data(file)

    if (index < lines.size)
      lines[index]
    else
      nil
    end
  end
end
open_database() click to toggle source
# File lib/milkode/grep/findgrep.rb, line 71
def open_database()
  # データベースファイル
  dbfile = Pathname(File.expand_path(@option.dbFile))

  # データベース開く
  if dbfile.exist?
    if !@grndb || @grndb.closed?
      @grndb = Milkode::GroongaDatabase.new
      @grndb.open_file(dbfile.to_s)
      @documents = @grndb.documents
      puts "open    : #{dbfile.to_s} open." unless @option.isSilent
    end
  else
    raise "error    : #{dbfile.to_s} not found!!"
  end
end
pickupRecords() click to toggle source
# File lib/milkode/grep/findgrep.rb, line 149
def pickupRecords
  raise unless @option.dbFile
  records = searchDatabase
  @result.time_stop
  records
end
searchAndPrint(stdout) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 110
def searchAndPrint(stdout)
  records = searchDatabase
  searchAndPrint2(stdout, records)
end
searchAndPrint2(stdout, records) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 115
def searchAndPrint2(stdout, records)
  unless (@option.dbFile)
    searchFromDir(stdout, @option.directory, 0)
  else
    searchFromDB(stdout, records, @option.directory)
  end

  @result.time_stop
  
  if (!@option.isSilent && !@option.dispHtml)
    if (@option.debugMode)
      stdout.puts
      stdout.puts "--- search --------"
      print_fpaths stdout, @result.search_files
      stdout.puts "--- match --------"
      print_fpaths stdout, @result.match_files
      stdout.puts "--- ignore-file --------"
      print_fpaths stdout, @result.ignore_files
      stdout.puts "--- ignore-dir --------"
      print_fpaths stdout, @result.prune_dirs
      stdout.puts "--- unreadable --------"
      print_fpaths stdout, @result.unreadable_files
    end

    unless (@option.colorHighlight)
      stdout.puts
    else
      stdout.puts HighLine::REVERSE + "------------------------------------------------------------" + HighLine::CLEAR
    end

    @result.print(stdout)
  end
end
searchDatabase() click to toggle source
# File lib/milkode/grep/findgrep.rb, line 210
def searchDatabase
  @documents.search(
    :patterns  => @patterns,
    :keywords  => @option.keywords,
    :paths     => @option.filePatterns,
    :packages  => @option.packages,
    :strict_packages  => @option.strict_packages,
    # :restpaths => ,
    :suffixs   => @option.suffixs
    # :offset    => ,
    # :limit     => ,
  )
end
searchFromDB(stdout, records, dir) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 160
def searchFromDB(stdout, records, dir)
  # ヒットしたレコード数
  stdout.puts "Found   : #{records.size} records." if (!@option.dispHtml && !@option.isSilent)

  # 検索にヒットしたファイルを実際に検索
  begin
    if (@option.gotoline > 0)
      records.each do |record|
        if FileTest.exist?(record.path)
          relative_path = convert_path(record.path)
          line = getTextLineno(relative_path, @option.gotoline)
          stdout.puts "#{relative_path}:#{@option.gotoline}:#{line}" if (line)
          @result.match_file_count += 1
          raise MatchCountOverError if (0 < @option.matchCountLimit && @option.matchCountLimit <= @result.match_file_count)
        end
      end
    elsif (@patterns.size > 0)
      records.each do |record|
        if (@option.groongaOnly)
          searchGroongaOnly(stdout, record)
        else
          searchFile(stdout, record.path, record.path) if FileTest.exist?(record.path)
        end
      end
    else
      records.each do |record|
        path = record.path
        stdout.puts convert_path(path)
        @result.match_file_count += 1
        raise MatchCountOverError if (0 < @option.matchCountLimit && @option.matchCountLimit <= @result.match_file_count)
      end
    end
  rescue MatchCountOverError
  end
end
strs2regs(strs) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 88
def strs2regs(strs)
  regs = []

  strs.each do |v|
    option = 0
    option |= Regexp::IGNORECASE if (@option.ignoreCase || (!@option.caseSensitive && Milkode::Util.downcase?(v)))
    regs << Regexp.new(Regexp.escape(v), option)
  end

  regs
end
strs2regs_simple(strs) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 100
def strs2regs_simple(strs)
  regs = []

  strs.each do |v|
    regs << Regexp.new(Regexp.escape(v), 0)
  end

  regs
end
time_s() click to toggle source
# File lib/milkode/grep/findgrep.rb, line 156
def time_s
  Gren::Util.time_s(@result.time)
end

Private Instance Methods

correctFileUser?(fpath) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 285
def correctFileUser?(fpath)
  @filePatterns.empty? ||
  @filePatterns.any? {|v| v.match File.basename(fpath) }
end
file2data(file) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 383
def file2data(file)
  FindGrep::file2lines(file, @option.kcode)
end
ignoreDir?(fpath) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 266
def ignoreDir?(fpath)
  FileTest.directory?(fpath) &&
  (GrenFileTest::ignoreDir?(File.basename(fpath)) || ignoreDirUser?(fpath))
end
ignoreDirUser?(fpath) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 272
def ignoreDirUser?(fpath)
  @ignoreDirs.any? {|v| v.match File.basename(fpath) }
end
ignoreFile?(fpath) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 277
def ignoreFile?(fpath)
  !correctFileUser?(fpath) ||
  GrenFileTest::ignoreFile?(fpath) ||
  ignoreFileUser?(fpath) ||
  GrenFileTest::binary?(fpath)
end
ignoreFileUser?(fpath) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 291
def ignoreFileUser?(fpath)
  @ignoreFiles.any? {|v| v.match File.basename(fpath) }
end
match?(line) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 415
def match?(line)
  match_datas = []
  @patternRegexps.each {|v| match_datas << v.match(line)}

  sub_matchs = []
  @subRegexps.each {|v| sub_matchs << v.match(line)}

  or_matchs = []
  @orRegexps.each {|v| or_matchs << v.match(line)}
  
  unless (@option.isMatchFile)
    result = match_datas.all? && !sub_matchs.any? && (or_matchs.empty? || or_matchs.any?)
  else
    result = first_condition(match_datas, sub_matchs, or_matchs)
  end
  result_match = match_datas + or_matchs
  result_match.delete(nil)

  return result, result_match
end
print_fpaths(stdout, data) click to toggle source
searchData(stdout, data, path) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 332
    def searchData(stdout, data, path)
      match_file = false

      data.each_with_index { |line, index|
        result, match_datas = match?(line)

        if ( result )
          unless (@option.dispHtml)
            # header = "#{path}:#{index + 1}:"
            header = "#{convert_path(path)}:#{index + 1}:"
            
            line = GrenSnip::snip(line, match_datas) unless (@option.noSnip)

            if @option.output_kcode != Kconv::UTF8
              header = Kconv.kconv(header, @option.output_kcode)
              line   = Kconv.kconv(line, @option.output_kcode)
            end

            unless (@option.colorHighlight)
              stdout.puts header + line
            else
              stdout.puts HighLine::BLUE + header + HighLine::CLEAR + GrenSnip::coloring(line, match_datas)
            end
          else
            line_no = index + 1
            line = GrenSnip::snip(line, match_datas) unless (@option.noSnip)
            
            stdout.puts <<EOF
<h2><a href="../::view#{path}">#{path}</a></h2>
<pre>
#{line_no} : #{CGI.escapeHTML(line)}
</pre>
EOF
          end

          unless match_file
            @result.match_file_count += 1
            @result.match_files << path if (@option.debugMode)
            match_file = true
            break if (@option.isMatchFile)
          end

          @result.match_count += 1
         if (0 < @option.matchCountLimit && @option.matchCountLimit <= @result.match_count)
           raise MatchCountOverError
         end
        end
      }
    end
searchFile(stdout, fpath, fpath_disp) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 296
def searchFile(stdout, fpath, fpath_disp)
  @result.count += 1
  @result.size += FileTest.size(fpath)

  # 除外ファイル
  if ignoreFile?(fpath)
    @result.ignore_files << fpath_disp if (@option.debugMode)
    return
  end
  
  @result.search_count += 1
  @result.search_size += FileTest.size(fpath)

  @result.search_files << fpath_disp if (@option.debugMode)

  open(fpath, "r") do |file|
    searchData(stdout, file2data(file), fpath_disp)
  end
end
searchFromDir(stdout, dir, depth) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 224
def searchFromDir(stdout, dir, depth)
  if (@option.depth != -1 && depth > @option.depth)
    return
  end
  
  Dir.foreach(dir) do |name|
    next if (name == '.' || name == '..')
      
    fpath = File.join(dir,name)
    fpath_disp = fpath.gsub(/^.\//, "")
    
    # 除外ディレクトリならばパス
    if ignoreDir?(fpath)
      @result.prune_dirs << fpath_disp if (@option.debugMode)
      next;
    end

    # 読み込み不可ならばパス
    unless FileTest.readable?(fpath)
      @result.unreadable_files << fpath_disp if (@option.debugMode)
      next
    end

    # ファイルならば中身を探索、ディレクトリならば再帰
    case File.ftype(fpath)
    when "directory"
      searchFromDir(stdout, fpath, depth + 1)
    when "file"
      searchFile(stdout, fpath, fpath_disp)
    end
  end
end
searchGroongaOnly(stdout, record) click to toggle source
# File lib/milkode/grep/findgrep.rb, line 317
def searchGroongaOnly(stdout, record)
  file_size = record.content.size
  
  @result.count += 1
  @result.size += file_size
  
  @result.search_count += 1
  @result.search_size += file_size
  
  @result.search_files << record.path if (@option.debugMode)

  searchData(stdout, record.content.split("\n"), record.path)
end