IHelpIndex uses Ferret to index all available RI documentation and lets you do full text searches over the index.
E.g. IHelpIndex.new.search("domain name lookup")
See Ferret::QueryParser for query string format.
Default place to save and load the index from.
# File lib/ihelp.rb, line 600 def initialize(use_global_index = (ENV["USER"] == "root")) @log_level = DEFAULT_LOG_LEVEL if use_global_index @index_path = GLOBAL_INDEX_PATH else @index_path = LOCAL_INDEX_PATH if not File.exist?(@index_path) and File.exist?(GLOBAL_INDEX_PATH) FileUtils.cp_r(GLOBAL_INDEX_PATH, @index_path) rescue nil elsif not File.exist?(@index_path) self.class.reindex_when_needed = true end end analyzer = IHelpAnalyzer.new have_index = File.exist? @index_path if have_index log "Loading existing index from #{@index_path}", 1 @index = Ferret::I.new( :key => :full_name, :path => @index_path, :analyzer => analyzer ) else log "Creating new index in #{@index_path}", 2 field_infos = Ferret::Index::FieldInfos.new(:term_vector => :no) field_infos.add_field(:name, :store => :yes, :index => :yes, :boost => 10.0) field_infos.add_field(:full_name, :store => :yes, :index => :untokenized, :boost => 0.0) field_infos.add_field(:content, :boost => 1.0, :store => :yes, :index => :yes, :term_vector => :with_positions_offsets) @index = Ferret::I.new( :key => :full_name, :field_infos => field_infos, :analyzer => analyzer ) end if self.class.reindex_when_needed and need_reindexing? reindex! end unless have_index @index.persist(@index_path) log "\nSaved index.", 2 end end
# File lib/ihelp.rb, line 683 def all_names IHelp.ri_driver.ri_reader.all_names.uniq end
Returns true if there already is an object named full_name
# File lib/ihelp.rb, line 669 def already_indexed? full_name @index[full_name] end
# File lib/ihelp.rb, line 741 def display return @display if @display @display = IHelp.ri_driver.display if ENV["PAGER"].to_s.size > 0 unless ENV["PAGER"] =~ /(^|\/)less\b.* -[a-zA-Z]*[rR]/ IHelp.no_colors = true end else ENV["PAGER"] = "less -R" end class << @display public :page attr_accessor :formatter end @display end
# File lib/ihelp.rb, line 673 def format_time(t) sec = t % 60 min = (t / 60) % 60 hour = (t / 3600) str = sec.to_i.to_s.rjust(2,'0') str = min.to_i.to_s.rjust(2,'0') + ":" + str str = hour.to_i.to_s.rjust(2,'0') + ":" + str if hour >= 1 str end
# File lib/ihelp.rb, line 652 def log str, level = 1 STDERR.puts str if level >= @log_level end
# File lib/ihelp.rb, line 687 def need_reindexing? all_names.size > @index.size end
# File lib/ihelp.rb, line 758 def page(*a,&b) display.page(*a,&b) end
Reindexes any non-indexed help documents.
# File lib/ihelp.rb, line 693 def reindex! start_size = @index.size names = all_names log "Indexing...", 2 nsz = names.size.to_s i = 0 names.each{|n| i += 1 next if (start_size > 0) and (already_indexed?(n)) if @log_level == DEFAULT_LOG_LEVEL amt_done = (i.to_f / names.size) pct = ("%.1f" % [100*amt_done]).rjust(5) STDERR.write "\r #{pct}% (#{i.to_s.rjust(nsz.size)}/#{nsz}) #{n}".ljust(80)[0,80] STDERR.flush end hd = if n.include? "#" IHelp.ri_driver.get_info_str(*(n.split("#") + [true])) elsif n.include? "::" IHelp.ri_driver.get_info_str(n) or IHelp.ri_driver.get_info_str(*n.reverse.split("::",2).reverse.map{|r| r.reverse }) else IHelp.ri_driver.get_info_str n end if hd.nil? log "skipping #{n} (not found)" next else log "indexing #{n}" end @index << { :name => hd.full_name, :full_name => n, :content => wrap_str(hd.to_text) } } if @log_level == DEFAULT_LOG_LEVEL amt_done = (i.to_f / names.size) pct = ("%.1f" % [100*amt_done]).rjust(5) STDERR.write "\r #{pct}% (#{i.to_s.rjust(nsz.size)}/#{nsz}) #{names.last}".ljust(80)[0,80] STDERR.flush STDERR.puts end if start_size != @index.size log "Optimizing index... (old size #{start_size}, current size #{@index.size})" @index.optimize end end
Searches for the terms in query and prints out first ten hits
See Ferret::QueryParser for query string format.
# File lib/ihelp.rb, line 783 def search(query) result = @index.search(query, :limit => 1000) init_display if IHelp.no_colors or `which less`.strip.empty? pre_tag = "<<" post_tag = ">>" else name_start = "\0033[32m" name_end = "\0033[0m" pre_tag = "\0033[36m" post_tag = "\0033[0m" end page do puts puts "=== #{result.total_hits} hits#{", showing first 1000" if result.total_hits > 1000} ".ljust(72,"=") puts result.hits.each_with_index do |hit, i| id, score = hit.doc, hit.score #puts hit.score puts "#{name_start}#{@index[id][:full_name]}#{name_end}" puts puts @index.highlight(query, id, :field => :content, :pre_tag => pre_tag, :post_tag => post_tag, :ellipsis => "...\n").to_s puts display.formatter.draw_line puts end puts "#{result.total_hits} hits" end p result.hits.map{|hit| @index[hit.doc][:full_name] } result end
# File lib/ihelp.rb, line 660 def time t = Time.now rv = yield log "Took #{Time.now - t}" rv end
Generated with the Darkfish Rdoc Generator 2.