milkode 0.9.5 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -1
- data/HISTORY.ja.rdoc +29 -0
- data/HISTORY.rdoc +14 -0
- data/VERSION +1 -1
- data/bin/gmilk +1 -1
- data/bin/milk +1 -1
- data/lib/milkode/cdstk/cdstk.rb +90 -38
- data/lib/milkode/cdstk/milkode_yaml.rb +6 -0
- data/lib/milkode/cdstk/yaml_file_wrapper.rb +4 -0
- data/lib/milkode/cdweb/app.rb +5 -5
- data/lib/milkode/cdweb/lib/command.rb +20 -4
- data/lib/milkode/cdweb/lib/database.rb +20 -16
- data/lib/milkode/cdweb/lib/grep.rb +6 -6
- data/lib/milkode/cdweb/lib/query.rb +36 -1
- data/lib/milkode/cdweb/lib/search_contents.rb +134 -19
- data/lib/milkode/cdweb/lib/search_fuzzy_gotoline.rb +162 -0
- data/lib/milkode/cdweb/lib/web_setting.rb +9 -1
- data/lib/milkode/cdweb/public/css/milkode.css +5 -0
- data/lib/milkode/cdweb/public/images/favicon.ico +0 -0
- data/lib/milkode/cdweb/public/js/milkode.js +46 -48
- data/lib/milkode/cdweb/views/index.haml +1 -0
- data/lib/milkode/cli.rb +6 -3
- data/lib/milkode/common/util.rb +19 -0
- data/lib/milkode/database/document_table.rb +40 -22
- data/lib/milkode/database/package_table.rb +1 -1
- data/lib/milkode/database/updater.rb +14 -7
- data/lib/milkode/findgrep/findgrep.rb +23 -11
- data/lib/milkode/grep/cli_grep.rb +1 -4
- data/milkode.gemspec +10 -5
- data/test/data/.gitignore.sjis +46 -0
- data/test/data/ignore_test_sjis/.gitignore +2 -0
- data/test/data/ignore_test_sjis/a.txt +1 -0
- data/test/test_cdstk.rb +2 -1
- data/test/test_ignore_setting.rb +9 -0
- data/test/test_query.rb +6 -0
- data/test/test_updater.rb +13 -1
- data/test/test_util.rb +10 -0
- metadata +17 -4
| @@ -88,20 +88,23 @@ module Milkode | |
| 88 88 |  | 
| 89 89 | 
             
                  # 検索
         | 
| 90 90 | 
             
                  result, total_records = [], 0
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                   | 
| 93 | 
            -
                     | 
| 94 | 
            -
                       | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 91 | 
            +
             | 
| 92 | 
            +
                  begin
         | 
| 93 | 
            +
                    unless is_not_search
         | 
| 94 | 
            +
                      result, total_records = @documents.search_with_match(
         | 
| 95 | 
            +
                        :patterns  => patterns,
         | 
| 96 | 
            +
                        :keywords  => keywords,
         | 
| 97 | 
            +
                        :paths     => paths,
         | 
| 98 | 
            +
                        :packages  => packages,
         | 
| 99 | 
            +
                        :strict_packages  => strict_packages,
         | 
| 100 | 
            +
                        :restpaths => fpaths,
         | 
| 101 | 
            +
                        :suffixs   => suffixs,
         | 
| 102 | 
            +
                        :fpath_or_packages => fpath_or_packages,
         | 
| 103 | 
            +
                        :offset    => offset,
         | 
| 104 | 
            +
                        :limit     => limit
         | 
| 105 | 
            +
                      )
         | 
| 106 | 
            +
                    end
         | 
| 107 | 
            +
                  rescue Groonga::TooLargeOffset
         | 
| 105 108 | 
             
                  end
         | 
| 106 109 |  | 
| 107 110 | 
             
                  # 結果
         | 
| @@ -198,8 +201,9 @@ module Milkode | |
| 198 201 | 
             
                def update_in(package)
         | 
| 199 202 | 
             
                  updater = Updater.new(@grndb, package.name)
         | 
| 200 203 | 
             
                  updater.set_package_ignore IgnoreSetting.new("/", package.ignore)
         | 
| 201 | 
            -
                  updater.enable_no_auto_ignore | 
| 202 | 
            -
                  updater.enable_update_with_git_pull | 
| 204 | 
            +
                  updater.enable_no_auto_ignore         if package.options[:no_auto_ignore]
         | 
| 205 | 
            +
                  updater.enable_update_with_git_pull   if package.options[:update_with_git_pull]
         | 
| 206 | 
            +
                  updater.enable_update_with_svn_update if package.options[:update_with_svn_update]
         | 
| 203 207 | 
             
                  updater.exec
         | 
| 204 208 | 
             
                  updater.result
         | 
| 205 209 | 
             
                end
         | 
| @@ -17,7 +17,7 @@ module Milkode | |
| 17 17 |  | 
| 18 18 | 
             
                def match_lines_stopover(patterns, max_match, start_index, is_sensitive)
         | 
| 19 19 | 
             
                  result = []
         | 
| 20 | 
            -
                  patternRegexps = strs2regs(patterns,  | 
| 20 | 
            +
                  patternRegexps = strs2regs(patterns, is_sensitive)
         | 
| 21 21 | 
             
                  index = start_index
         | 
| 22 22 |  | 
| 23 23 | 
             
                  lines = @content.split($/)
         | 
| @@ -45,7 +45,7 @@ module Milkode | |
| 45 45 |  | 
| 46 46 | 
             
                def match_lines_and(patterns, is_sensitive)
         | 
| 47 47 | 
             
                  result = []
         | 
| 48 | 
            -
                  patternRegexps = strs2regs(patterns,  | 
| 48 | 
            +
                  patternRegexps = strs2regs(patterns, is_sensitive)
         | 
| 49 49 | 
             
                  index = 0
         | 
| 50 50 |  | 
| 51 51 | 
             
                  @content.each_line do |line|
         | 
| @@ -63,7 +63,7 @@ module Milkode | |
| 63 63 | 
             
                end
         | 
| 64 64 |  | 
| 65 65 | 
             
                def one_match_and(patterns, is_sensitive)
         | 
| 66 | 
            -
                  patternRegexps = strs2regs(patterns,  | 
| 66 | 
            +
                  patternRegexps = strs2regs(patterns, is_sensitive)
         | 
| 67 67 | 
             
                  index = 0
         | 
| 68 68 |  | 
| 69 69 | 
             
                  @content.each_line do |line|
         | 
| @@ -82,13 +82,13 @@ module Milkode | |
| 82 82 |  | 
| 83 83 | 
             
                private
         | 
| 84 84 |  | 
| 85 | 
            -
                def strs2regs(strs,  | 
| 85 | 
            +
                def strs2regs(strs, is_sensitive)
         | 
| 86 86 | 
             
                  regs = []
         | 
| 87 87 |  | 
| 88 88 | 
             
                  strs.each do |v|
         | 
| 89 89 | 
             
                    option = 0
         | 
| 90 | 
            -
                    option |= Regexp::IGNORECASE if ( | 
| 91 | 
            -
                    regs | 
| 90 | 
            +
                    option |= Regexp::IGNORECASE if (!is_sensitive && Util::downcase?(v))
         | 
| 91 | 
            +
                    regs   << Regexp.new(Regexp.escape(v), option)
         | 
| 92 92 | 
             
                  end
         | 
| 93 93 |  | 
| 94 94 | 
             
                  regs
         | 
| @@ -18,6 +18,7 @@ module Milkode | |
| 18 18 | 
             
                           ['suffix',   's'],
         | 
| 19 19 | 
             
                           ['fp'],          # fpath or package
         | 
| 20 20 | 
             
                           ['keyword',  'k'],
         | 
| 21 | 
            +
                           ['gotoline', 'g'],
         | 
| 21 22 | 
             
                          ]
         | 
| 22 23 |  | 
| 23 24 | 
             
                def initialize(str)
         | 
| @@ -31,7 +32,11 @@ module Milkode | |
| 31 32 | 
             
                end
         | 
| 32 33 |  | 
| 33 34 | 
             
                def empty?
         | 
| 34 | 
            -
                  keywords.size == 0 && packages.size == 0 && fpaths.size == 0 && suffixs.size == 0 && fpath_or_packages.size == 0
         | 
| 35 | 
            +
                  keywords.size == 0 && packages.size == 0 && fpaths.size == 0 && suffixs.size == 0 && fpath_or_packages.size == 0 && gotolines.size == 0
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def only_keywords
         | 
| 39 | 
            +
                  packages.size == 0 && fpaths.size == 0 && suffixs.size == 0 && fpath_or_packages.size == 0 && gotolines.size == 0
         | 
| 35 40 | 
             
                end
         | 
| 36 41 |  | 
| 37 42 | 
             
                def keywords
         | 
| @@ -59,6 +64,10 @@ module Milkode | |
| 59 64 | 
             
                  calc_param(4)
         | 
| 60 65 | 
             
                end
         | 
| 61 66 |  | 
| 67 | 
            +
                def gotolines
         | 
| 68 | 
            +
                  calc_param(5)
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 62 71 | 
             
                def conv_keywords_to_fpath
         | 
| 63 72 | 
             
                  s = query_string.split.map {|v|
         | 
| 64 73 | 
             
                    if keywords.include? v
         | 
| @@ -83,6 +92,32 @@ module Milkode | |
| 83 92 | 
             
                  Query.new(s)
         | 
| 84 93 | 
             
                end
         | 
| 85 94 |  | 
| 95 | 
            +
                # 'name def test' -> 'fp:name def test'
         | 
| 96 | 
            +
                def conv_head_keyword_to_fpath_or_packages
         | 
| 97 | 
            +
                  s = query_string.split.map {|v|
         | 
| 98 | 
            +
                    if keywords[0].include? v
         | 
| 99 | 
            +
                      "fp:#{v}"
         | 
| 100 | 
            +
                    else
         | 
| 101 | 
            +
                      v
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                  }.join(' ')
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  Query.new(s)
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                # 'cdstk.rb:11' -> 'g:cdstk.rb:11'
         | 
| 109 | 
            +
                def conv_fuzzy_gotoline
         | 
| 110 | 
            +
                  s = query_string.split.map {|v|
         | 
| 111 | 
            +
                    if keywords[0].include? v
         | 
| 112 | 
            +
                      "g:#{v}"
         | 
| 113 | 
            +
                    else
         | 
| 114 | 
            +
                      v
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
                  }.join(' ')
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  Query.new(s)
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 86 121 | 
             
                private
         | 
| 87 122 |  | 
| 88 123 | 
             
                def calc_param(index)
         | 
| @@ -9,11 +9,11 @@ require 'milkode/cdweb/lib/query' | |
| 9 9 | 
             
            require 'milkode/cdweb/lib/grep'
         | 
| 10 10 | 
             
            require 'milkode/cdweb/lib/mkurl'
         | 
| 11 11 | 
             
            require 'milkode/common/util'
         | 
| 12 | 
            +
            require 'milkode/cdweb/lib/search_fuzzy_gotoline'
         | 
| 12 13 |  | 
| 13 14 | 
             
            module Milkode
         | 
| 14 15 | 
             
              class SearchContents
         | 
| 15 16 | 
             
                attr_reader :total_records
         | 
| 16 | 
            -
                attr_reader :elapsed
         | 
| 17 17 | 
             
                attr_reader :page
         | 
| 18 18 |  | 
| 19 19 | 
             
                DISP_NUM = 20              # 1ページの表示数
         | 
| @@ -23,7 +23,7 @@ module Milkode | |
| 23 23 |  | 
| 24 24 | 
             
                MATH_FILE_DISP  = 3        # マッチファイルの最大表示数
         | 
| 25 25 | 
             
                MATH_FILE_LIMIT = MATH_FILE_DISP + 1 # マッチファイルの検索リミット数
         | 
| 26 | 
            -
             | 
| 26 | 
            +
             | 
| 27 27 | 
             
                def initialize(path, params, query)
         | 
| 28 28 | 
             
                  @path = path
         | 
| 29 29 | 
             
                  @params = params
         | 
| @@ -33,23 +33,48 @@ module Milkode | |
| 33 33 | 
             
                  @line = params[:line].to_i
         | 
| 34 34 | 
             
                  @is_onematch = params[:onematch] == 'on'
         | 
| 35 35 | 
             
                  @is_sensitive = params[:sensitive] == 'on'
         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
                   | 
| 39 | 
            -
             | 
| 40 | 
            -
                   | 
| 36 | 
            +
                  @searcher_fuzzy_gotoline = nil
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  # 検索1 : クエリーそのまま
         | 
| 39 | 
            +
                  @records, @total_records = Database.instance.search(@q.keywords, @q.multi_match_keywords, @q.packages, path, @q.fpaths, @q.suffixs, @q.fpath_or_packages, @offset, LIMIT_NUM)
         | 
| 40 | 
            +
                  grep_contents(@q.keywords)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  # 検索2 : マッチしなかった時におすすめクエリーがある場合
         | 
| 43 | 
            +
                  if @match_records.empty?
         | 
| 44 | 
            +
                    if recommended_fuzzy_gotoline?
         | 
| 45 | 
            +
                      # 専用の Searcher を作成
         | 
| 46 | 
            +
                      @searcher_fuzzy_gotoline = SearchFuzzyGotoLine.new(@path, @params, @q)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      # 結果をコピーする
         | 
| 49 | 
            +
                      @total_records = @searcher_fuzzy_gotoline.total_records
         | 
| 50 | 
            +
                      @match_records = @searcher_fuzzy_gotoline.match_records
         | 
| 51 | 
            +
                      @next_index    = @searcher_fuzzy_gotoline.next_index
         | 
| 52 | 
            +
                      @end_index     = @searcher_fuzzy_gotoline.end_index
         | 
| 53 | 
            +
                      @next_line     = nil
         | 
| 54 | 
            +
                      
         | 
| 55 | 
            +
                    elsif recommended_fpath_or_packages?
         | 
| 56 | 
            +
                      # おすすめクエリーに変換
         | 
| 57 | 
            +
                      q2 = @q.conv_head_keyword_to_fpath_or_packages
         | 
| 58 | 
            +
                      
         | 
| 59 | 
            +
                      # 検索
         | 
| 60 | 
            +
                      @records, @total_records = Database.instance.search(q2.keywords, q2.multi_match_keywords, q2.packages, path, q2.fpaths, q2.suffixs, q2.fpath_or_packages, @offset, LIMIT_NUM)
         | 
| 61 | 
            +
                      
         | 
| 62 | 
            +
                      # 再grep
         | 
| 63 | 
            +
                      grep_contents(q2.keywords)
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
                  
         | 
| 67 | 
            +
                  # 検索3 : マッチするファイル
         | 
| 41 68 | 
             
                  @match_files = []
         | 
| 42 69 | 
             
                  if @offset == 0 && @line == 0
         | 
| 43 70 | 
             
                    t = 0
         | 
| 44 71 |  | 
| 45 72 | 
             
                    if (@path != "")
         | 
| 46 | 
            -
                      @match_files, t | 
| 73 | 
            +
                      @match_files, t = Database.instance.search([], @q.multi_match_keywords, @q.packages, path, @q.fpaths + @q.keywords, @q.suffixs, @q.fpath_or_packages, @offset, MATH_FILE_LIMIT)
         | 
| 47 74 | 
             
                    else
         | 
| 48 | 
            -
                      @match_files, t | 
| 75 | 
            +
                      @match_files, t = Database.instance.search([], @q.multi_match_keywords, @q.packages, path, @q.fpaths, @q.suffixs, @q.fpath_or_packages + @q.keywords, @offset, MATH_FILE_LIMIT)
         | 
| 49 76 | 
             
                    end
         | 
| 50 77 | 
             
                  end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  grep_contents
         | 
| 53 78 | 
             
                end
         | 
| 54 79 |  | 
| 55 80 | 
             
                def query
         | 
| @@ -85,11 +110,59 @@ module Milkode | |
| 85 110 | 
             
                  end
         | 
| 86 111 |  | 
| 87 112 | 
             
                  <<EOF
         | 
| 88 | 
            -
            #{ | 
| 113 | 
            +
            #{recommended_contents}
         | 
| 89 114 | 
             
            #{match_groups.map{|g|result_match_record(g)}.join}
         | 
| 90 115 | 
             
            EOF
         | 
| 91 116 | 
             
                end
         | 
| 92 117 |  | 
| 118 | 
            +
                def recommended_contents
         | 
| 119 | 
            +
                  contents = []
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                  str = recommended_query_contents
         | 
| 122 | 
            +
                  contents << str unless str.empty?
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                  str = match_files_contents
         | 
| 125 | 
            +
                  contents << str unless str.empty?
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  unless contents.empty?
         | 
| 128 | 
            +
                    contents.join
         | 
| 129 | 
            +
                  else
         | 
| 130 | 
            +
                    ""
         | 
| 131 | 
            +
                  end
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                def recommended_fuzzy_gotoline?
         | 
| 135 | 
            +
                  @q.keywords.size == 1 && @q.only_keywords && Util::fuzzy_gotoline_keyword?(@q.keywords[0])
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                def recommended_fpath_or_packages?
         | 
| 139 | 
            +
                  @q.keywords.size >= 2 && @q.only_keywords
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                def recommended_query_contents
         | 
| 143 | 
            +
                  if recommended_fuzzy_gotoline?
         | 
| 144 | 
            +
                    conv_query   = @q.conv_fuzzy_gotoline
         | 
| 145 | 
            +
                    tmpp         = @params.clone
         | 
| 146 | 
            +
                    tmpp[:query] = conv_query.query_string
         | 
| 147 | 
            +
                    url          = Mkurl.new(@path, tmpp).inherit_query_shead
         | 
| 148 | 
            +
                    <<EOS
         | 
| 149 | 
            +
            <dt class='result-file'>#{img_icon('document-new-4.png')}<a href='#{url}'>#{conv_query.query_string}</a></dt>
         | 
| 150 | 
            +
            <hr>
         | 
| 151 | 
            +
            EOS
         | 
| 152 | 
            +
                  elsif recommended_fpath_or_packages?
         | 
| 153 | 
            +
                    conv_query   = @q.conv_head_keyword_to_fpath_or_packages
         | 
| 154 | 
            +
                    tmpp         = @params.clone
         | 
| 155 | 
            +
                    tmpp[:query] = conv_query.query_string
         | 
| 156 | 
            +
                    url          = Mkurl.new(@path, tmpp).inherit_query_shead
         | 
| 157 | 
            +
                    <<EOS
         | 
| 158 | 
            +
            <dt class='result-file'>#{img_icon('document-new-4.png')}<a href='#{url}'>#{conv_query.query_string}</a></dt>
         | 
| 159 | 
            +
            <hr>
         | 
| 160 | 
            +
            EOS
         | 
| 161 | 
            +
                  else
         | 
| 162 | 
            +
                    ""
         | 
| 163 | 
            +
                  end
         | 
| 164 | 
            +
              end
         | 
| 165 | 
            +
                
         | 
| 93 166 | 
             
                def match_files_contents
         | 
| 94 167 | 
             
                  unless @match_files.empty?
         | 
| 95 168 | 
             
                    is_and_more = @match_files.size >= MATH_FILE_LIMIT
         | 
| @@ -107,7 +180,7 @@ EOF | |
| 107 180 | 
             
                    ""
         | 
| 108 181 | 
             
                  end
         | 
| 109 182 | 
             
                end
         | 
| 110 | 
            -
             | 
| 183 | 
            +
             | 
| 111 184 | 
             
                def html_pagination
         | 
| 112 185 | 
             
                  return "" if @q.empty?
         | 
| 113 186 | 
             
                  return "" if next_offset >= @total_records
         | 
| @@ -123,11 +196,19 @@ EOF | |
| 123 196 | 
             
                  @match_records.size
         | 
| 124 197 | 
             
                end
         | 
| 125 198 |  | 
| 199 | 
            +
                def directjump?
         | 
| 200 | 
            +
                  @searcher_fuzzy_gotoline && @searcher_fuzzy_gotoline.directjump?
         | 
| 201 | 
            +
                end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                def directjump_url
         | 
| 204 | 
            +
                  @searcher_fuzzy_gotoline.directjump_url
         | 
| 205 | 
            +
                end
         | 
| 206 | 
            +
             | 
| 126 207 | 
             
                private
         | 
| 127 208 |  | 
| 128 209 | 
             
                MatchRecord = Struct.new(:record, :match_line)
         | 
| 129 210 |  | 
| 130 | 
            -
                def grep_contents
         | 
| 211 | 
            +
                def grep_contents(keywords)
         | 
| 131 212 | 
             
                  @match_records = []
         | 
| 132 213 | 
             
                  @end_index = @next_index = @records.size
         | 
| 133 214 | 
             
                  @next_line = nil
         | 
| @@ -137,7 +218,7 @@ EOF | |
| 137 218 |  | 
| 138 219 | 
             
                      if @is_onematch
         | 
| 139 220 | 
             
                        grep = Grep.new(record.content)
         | 
| 140 | 
            -
                        match_line = grep.one_match_and( | 
| 221 | 
            +
                        match_line = grep.one_match_and(keywords, @is_sensitive)
         | 
| 141 222 | 
             
                        @match_records << MatchRecord.new(record, match_line) if match_line
         | 
| 142 223 |  | 
| 143 224 | 
             
                        if @match_records.size >= DISP_NUM
         | 
| @@ -146,7 +227,7 @@ EOF | |
| 146 227 | 
             
                          break
         | 
| 147 228 | 
             
                        end
         | 
| 148 229 | 
             
                      else
         | 
| 149 | 
            -
                        break if grep_match_lines_stopover(record, index)
         | 
| 230 | 
            +
                        break if grep_match_lines_stopover(record, index, keywords)
         | 
| 150 231 | 
             
                      end
         | 
| 151 232 | 
             
                    else
         | 
| 152 233 | 
             
                      @match_records << MatchRecord.new(record, Grep::MatchLineResult.new(0, nil))
         | 
| @@ -160,9 +241,9 @@ EOF | |
| 160 241 | 
             
                  end
         | 
| 161 242 | 
             
                end
         | 
| 162 243 |  | 
| 163 | 
            -
                def grep_match_lines_stopover(record, index)
         | 
| 244 | 
            +
                def grep_match_lines_stopover(record, index, keywords)
         | 
| 164 245 | 
             
                  grep = Grep.new(record.content)      
         | 
| 165 | 
            -
                  r = grep.match_lines_stopover( | 
| 246 | 
            +
                  r = grep.match_lines_stopover(keywords, DISP_NUM - @match_records.size, (index == 0) ? @line : 0, @is_sensitive)
         | 
| 166 247 |  | 
| 167 248 | 
             
                  r[:result].each do |match_line|
         | 
| 168 249 | 
             
                    @match_records << MatchRecord.new(record, match_line) if match_line
         | 
| @@ -197,7 +278,7 @@ EOF | |
| 197 278 | 
             
                  url = "/home/" + record_link(record)
         | 
| 198 279 |  | 
| 199 280 | 
             
                  <<EOS
         | 
| 200 | 
            -
                <dt class='result-record'><a href='#{url + "#n#{coderay.highlight_lines[0]}"}'>#{Util::relative_path record.shortpath, @path}</a | 
| 281 | 
            +
                <dt class='result-record'><a href='#{url + "#n#{coderay.highlight_lines[0]}"}'>#{Util::relative_path record.shortpath, @path}</a>#{result_refinement(record)}</dt>
         | 
| 201 282 | 
             
                <dd>
         | 
| 202 283 | 
             
            #{coderay.to_html_anchorlink(url)}
         | 
| 203 284 | 
             
                </dd>
         | 
| @@ -226,6 +307,40 @@ EOS | |
| 226 307 | 
             
                  Mkurl.new(record.shortpath, @params).inherit_query_shead
         | 
| 227 308 | 
             
                end
         | 
| 228 309 |  | 
| 310 | 
            +
                def refinement_suffix(suffix)
         | 
| 311 | 
            +
                  params = @params.clone
         | 
| 312 | 
            +
                  params[:query] = [@params[:query], "s:#{suffix}"].join(" ")
         | 
| 313 | 
            +
                  "/home/" + Mkurl.new(@path, params).inherit_query_shead
         | 
| 314 | 
            +
                end
         | 
| 315 | 
            +
             | 
| 316 | 
            +
                def refinement_directory(path)
         | 
| 317 | 
            +
                  "/home/" + Mkurl.new(path, @params).inherit_query_shead
         | 
| 318 | 
            +
                end
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                def result_refinement(record)
         | 
| 321 | 
            +
                  refinements = []
         | 
| 322 | 
            +
             | 
| 323 | 
            +
                  # 拡張子で絞り込み
         | 
| 324 | 
            +
                  refinements << "<a href='#{refinement_suffix(record.suffix)}'>.#{record.suffix}で絞り込み</a>" if record.suffix
         | 
| 325 | 
            +
             | 
| 326 | 
            +
                  # ディレクトリで絞り込み
         | 
| 327 | 
            +
                  path    = Util::relative_path(record.shortpath, @path)
         | 
| 328 | 
            +
                  dirname = path.to_s.split('/')[-2]
         | 
| 329 | 
            +
                  refinements << "<a href='#{refinement_directory(record.shortpath + '/..')}'>#{dirname}/以下で再検索</a>" if dirname
         | 
| 330 | 
            +
             | 
| 331 | 
            +
                  unless refinements.empty?
         | 
| 332 | 
            +
                    space1            = '      '
         | 
| 333 | 
            +
                    space2            = '  ,  '
         | 
| 334 | 
            +
             | 
| 335 | 
            +
                    <<EOF
         | 
| 336 | 
            +
            #{space1}<span id="result-refinement">[#{refinements.join(space2)}]</span>
         | 
| 337 | 
            +
            EOF
         | 
| 338 | 
            +
                  else
         | 
| 339 | 
            +
                    ''
         | 
| 340 | 
            +
                  end
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                end
         | 
| 343 | 
            +
             | 
| 229 344 | 
             
              end
         | 
| 230 345 | 
             
            end
         | 
| 231 346 |  | 
| @@ -0,0 +1,162 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # @file 
         | 
| 4 | 
            +
            # @brief  曖昧ジャンプ
         | 
| 5 | 
            +
            # @author ongaeshi
         | 
| 6 | 
            +
            # @date   2012/07/08
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require 'milkode/cdweb/lib/query'
         | 
| 9 | 
            +
            require 'milkode/cdweb/lib/grep'
         | 
| 10 | 
            +
            require 'milkode/cdweb/lib/mkurl'
         | 
| 11 | 
            +
            require 'milkode/common/util'
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            module Milkode
         | 
| 14 | 
            +
              class SearchFuzzyGotoLine
         | 
| 15 | 
            +
                attr_reader :total_records
         | 
| 16 | 
            +
                attr_reader :match_records
         | 
| 17 | 
            +
                attr_reader :next_index
         | 
| 18 | 
            +
                attr_reader :end_index
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                DISP_NUM = 20              # 1ページの表示数
         | 
| 21 | 
            +
                LIMIT_NUM = 50             # 最大検索ファイル数
         | 
| 22 | 
            +
                NTH = 3                    # 表示範囲
         | 
| 23 | 
            +
                COL_LIMIT = 200            # 1行の桁制限
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def initialize(path, params, query)
         | 
| 26 | 
            +
                  @path = path
         | 
| 27 | 
            +
                  @params = params
         | 
| 28 | 
            +
                  @q = query
         | 
| 29 | 
            +
                  @page = params[:page].to_i || 0
         | 
| 30 | 
            +
                  @offset = params[:offset].to_i
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  # 検索クエリを解析
         | 
| 33 | 
            +
                  gotolines = Util::parse_gotoline(@q.gotolines + @q.keywords)
         | 
| 34 | 
            +
                  @gotoline = gotolines[0]
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  # 検索
         | 
| 37 | 
            +
                  fpaths = @q.fpaths + @gotoline[0]
         | 
| 38 | 
            +
                  @records, @total_records = Database.instance.search([], @q.multi_match_keywords, @q.packages, path, fpaths, @q.suffixs, @q.fpath_or_packages, @offset, LIMIT_NUM)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  # 検索結果を表示
         | 
| 41 | 
            +
                  grep_contents
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def query
         | 
| 45 | 
            +
                  @q.query_string
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def next_offset
         | 
| 49 | 
            +
                  @offset + @next_index
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def data_range
         | 
| 53 | 
            +
                  @offset..(@offset + @end_index)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def html_contents
         | 
| 57 | 
            +
                  match_groups = @match_records.reduce([]) do |g, m|
         | 
| 58 | 
            +
                    # 近接マッチ無効
         | 
| 59 | 
            +
                    g << [m]
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                  
         | 
| 62 | 
            +
                  <<EOF
         | 
| 63 | 
            +
            #{match_groups.map{|g|result_match_record(g)}.join}
         | 
| 64 | 
            +
            EOF
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def html_pagination
         | 
| 68 | 
            +
                  return "" if @q.empty?
         | 
| 69 | 
            +
                  return "" if next_offset >= @total_records
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  return <<EOF
         | 
| 72 | 
            +
            <div class='pagination pagination-centered'>
         | 
| 73 | 
            +
            #{pagination_link(next_offset, @next_line, "next >>")}
         | 
| 74 | 
            +
            </div>
         | 
| 75 | 
            +
            EOF
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def match_num
         | 
| 79 | 
            +
                  @match_records.size
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def directjump?
         | 
| 83 | 
            +
                  match_num == 1
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                def directjump_url
         | 
| 87 | 
            +
                  path   = File.join('/home', @match_records[0].record.shortpath)
         | 
| 88 | 
            +
                  lineno = "#n#{@gotoline[1]}"
         | 
| 89 | 
            +
                  Mkurl.new(path, @params).inherit_query_shead + lineno
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                private
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                MatchRecord = Struct.new(:record, :match_line)
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                def grep_contents
         | 
| 97 | 
            +
                  @match_records = []
         | 
| 98 | 
            +
                  @end_index = @next_index = @records.size
         | 
| 99 | 
            +
                  @next_line = nil
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  @records.each_with_index do |record, index|
         | 
| 102 | 
            +
                    lineidx = @gotoline[1] - 1
         | 
| 103 | 
            +
                    
         | 
| 104 | 
            +
                    if (lineidx < record.content.split("\n").size)
         | 
| 105 | 
            +
                      @match_records << MatchRecord.new(record, Grep::MatchLineResult.new(lineidx, nil))
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                      if @match_records.size >= DISP_NUM
         | 
| 108 | 
            +
                        @end_index  = index
         | 
| 109 | 
            +
                        @next_index = index + 1
         | 
| 110 | 
            +
                        break
         | 
| 111 | 
            +
                      end
         | 
| 112 | 
            +
                    end
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                def result_match_record(match_group)
         | 
| 117 | 
            +
                  record = match_group[0].record
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                  first_index = match_group[0].match_line.index - NTH
         | 
| 120 | 
            +
                  last_index  = match_group[-1].match_line.index + NTH
         | 
| 121 | 
            +
                  match_lines = match_group.map{|m| m.match_line}
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  coderay = CodeRayWrapper.new(record.content, record.shortpath, match_lines)
         | 
| 124 | 
            +
                  coderay.col_limit(COL_LIMIT)
         | 
| 125 | 
            +
                  coderay.set_range(first_index..last_index)
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  url = "/home/" + record_link(record)
         | 
| 128 | 
            +
                  
         | 
| 129 | 
            +
                  <<EOS
         | 
| 130 | 
            +
                <dt class='result-record'><a href='#{url + "#n#{coderay.highlight_lines[0]}"}'>#{Util::relative_path record.shortpath, @path}</a></dt>
         | 
| 131 | 
            +
                <dd>
         | 
| 132 | 
            +
            #{coderay.to_html_anchorlink(url)}
         | 
| 133 | 
            +
                </dd>
         | 
| 134 | 
            +
            EOS
         | 
| 135 | 
            +
                end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                def pagination_link(offset, line, label)
         | 
| 138 | 
            +
                  tmpp = @params.clone
         | 
| 139 | 
            +
                  tmpp[:offset] = offset.to_s
         | 
| 140 | 
            +
                  tmpp[:line] = line.to_s
         | 
| 141 | 
            +
                  href = Mkurl.new("", tmpp).inherit_query_shead_offset
         | 
| 142 | 
            +
                  pagination_span("<a href='#{href}' rel='next'>#{label}</a>")
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                def pagination_span(content)
         | 
| 146 | 
            +
                  "<ul><li>#{content}</li></ul>\n"
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                def result_record(record)
         | 
| 150 | 
            +
                  <<EOS
         | 
| 151 | 
            +
                <dt class='result-file'>#{file_or_dirimg(true)}<a href='#{"/home/" + record_link(record)}'>#{Util::relative_path record.shortpath, @path}</a></dt>
         | 
| 152 | 
            +
            EOS
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                def record_link(record)
         | 
| 156 | 
            +
                  Mkurl.new(record.shortpath, @params).inherit_query_shead
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
              end
         | 
| 160 | 
            +
            end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
             |