Class: FindGrep::FindGrep

Inherits:
Object
  • Object
show all
Defined in:
lib/milkode/findgrep/findgrep.rb

Defined Under Namespace

Classes: MatchCountOverError, Option

Constant Summary collapse

DEFAULT_OPTION =
Option.new([],
[],
".",
-1,
false,
false,
false,
false,
[],
[],
[],
[],
[],
Platform.get_shell_kcode,
false,
nil,
false,
false,
false,
-1,
[],
-1)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(patterns, option) ⇒ FindGrep

Returns a new instance of FindGrep.



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/milkode/findgrep/findgrep.rb', line 68

def initialize(patterns, option)
  @patterns = patterns
  @option = option
  @patternRegexps = strs2regs(patterns, @option.ignoreCase)
  @subRegexps = strs2regs(option.patternsNot, @option.ignoreCase)
  @orRegexps = strs2regs(option.patternsOr, @option.ignoreCase)
  @filePatterns = (!@option.dbFile) ? strs2regs(option.filePatterns) : []
  @ignoreFiles = strs2regs(option.ignoreFiles)
  @ignoreDirs = strs2regs(option.ignoreDirs)
  @result = Result.new(option.directory)
  open_database if (@option.dbFile)
end

Instance Attribute Details

#documentsObject (readonly)

Returns the value of attribute documents.



66
67
68
# File 'lib/milkode/findgrep/findgrep.rb', line 66

def documents
  @documents
end

Class Method Details

.file2lines(file, kcode) ⇒ Object



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'lib/milkode/findgrep/findgrep.rb', line 486

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

Instance Method Details

#and_expression(key, list) ⇒ Object



276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/milkode/findgrep/findgrep.rb', line 276

def and_expression(key, list)
  sub = nil
  
  list.each do |word|
    e = key =~ word
    if sub.nil?
      sub = e
    else
      sub &= e
    end
  end

  sub
end

#first_condition(match_datas, sub_matchs, or_matchs) ⇒ Object



535
536
537
538
539
540
541
# File 'lib/milkode/findgrep/findgrep.rb', line 535

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) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/milkode/findgrep/findgrep.rb', line 193

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_databaseObject



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/milkode/findgrep/findgrep.rb', line 81

def open_database()
  # データベース開く
  dbfile = Pathname(File.expand_path(@option.dbFile))
  
  if dbfile.exist?
    Groonga::Database.open(dbfile.to_s)
    puts "open    : #{dbfile} open." unless @option.isSilent
  else
    raise "error    : #{dbfile.to_s} not found!!"
  end
  
  # ドキュメントを取
  @documents = Groonga::Context.default["documents"]
end

#pickupRecordsObject



142
143
144
145
146
147
# File 'lib/milkode/findgrep/findgrep.rb', line 142

def pickupRecords
  raise unless @option.dbFile
  records = searchDatabase
  @result.time_stop
  records
end

#searchAndPrint(stdout) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/milkode/findgrep/findgrep.rb', line 108

def searchAndPrint(stdout)
  unless (@option.dbFile)
    searchFromDir(stdout, @option.directory, 0)
  else
    searchFromDB(stdout, @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

#searchDatabaseObject



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/milkode/findgrep/findgrep.rb', line 207

def searchDatabase
  # 全てのパターンを検索
  table = @documents.select do |record|
    expression = nil

    # パターン(マッチ行)
    @patterns.each do |word|
      sub_expression = record.content =~ word
      if expression.nil?
        expression = sub_expression
      else
        expression &= sub_expression
      end
    end

    # キーワード(絞り込むための手がかり)
    @option.keywords.each do |word|
      sub_expression = record.content =~ word
      sub_expression |= record.path =~ word
      if expression.nil?
        expression = sub_expression
      else
        expression &= sub_expression
      end
    end
    
    # パッケージ(OR)
    pe = package_expression(record, @option.packages)
    if (pe)
      if expression.nil?
        expression = pe
      else
        expression &= pe
      end
    end
    
    # パス
    @option.filePatterns.each do |word|
      sub_expression = record.path =~ word
      if expression.nil?
        expression = sub_expression
      else
        expression &= sub_expression
      end
    end

    # 拡張子(OR)
    se = suffix_expression(record) 
    if (se)
      if expression.nil?
        expression = se
      else
        expression &= se
      end
    end
    
    # 検索式
    expression
  end
  
  # @todo オプションで出来るようにする?
  # タイムスタンプでソート
  # records = table.sort([{:key => "_score", :order => "descending"},
  #                       {:key => "timestamp", :order => "descending"}])

  # ファイル名でソート
  table.sort([{:key => "shortpath", :order => "ascending"}])
end

#searchFromDB(stdout, dir) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/milkode/findgrep/findgrep.rb', line 153

def searchFromDB(stdout, dir)
  # データベースを検索
  records = searchDatabase

  # ヒットしたレコード数
  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 = Milkode::Util::relative_path(record.path, Dir.pwd).to_s
          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
        relative_path = Milkode::Util::relative_path(path, Dir.pwd).to_s
        stdout.puts relative_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, ignore = false) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/milkode/findgrep/findgrep.rb', line 96

def strs2regs(strs, ignore = false)
  regs = []

  strs.each do |v|
    option = 0
    option |= Regexp::IGNORECASE if (ignore)
    regs << Regexp.new(v, option)
  end

  regs
end

#time_sObject



149
150
151
# File 'lib/milkode/findgrep/findgrep.rb', line 149

def time_s
  Gren::Util::time_s(@result.time)
end