milkode 0.8.1 → 0.9.0
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 -0
- data/HISTORY.ja.rdoc +36 -0
- data/HISTORY.rdoc +20 -0
- data/VERSION +1 -1
- data/bin/gmilk +1 -1
- data/bin/milk +1 -1
- data/lib/milkode/cdweb/app.rb +69 -8
- data/lib/milkode/cdweb/lib/coderay_html2.rb +24 -16
- data/lib/milkode/cdweb/lib/coderay_wrapper.rb +3 -1
- data/lib/milkode/cdweb/lib/command.rb +21 -4
- data/lib/milkode/cdweb/lib/database.rb +12 -6
- data/lib/milkode/cdweb/lib/grep.rb +8 -6
- data/lib/milkode/cdweb/lib/mkurl.rb +7 -2
- data/lib/milkode/cdweb/lib/query.rb +36 -1
- data/lib/milkode/cdweb/lib/search_contents.rb +54 -13
- data/lib/milkode/cdweb/lib/search_files.rb +4 -4
- data/lib/milkode/cdweb/lib/search_gotoline.rb +151 -0
- data/lib/milkode/cdweb/public/css/coderay-patch.css +24 -0
- data/lib/milkode/cdweb/public/css/milkode.css +39 -5
- data/lib/milkode/cdweb/public/js/milkode.js +19 -1
- data/lib/milkode/cdweb/views/help.haml +13 -0
- data/lib/milkode/cdweb/views/layout.haml +4 -4
- data/lib/milkode/cdweb/views/search_form.haml +19 -23
- data/lib/milkode/cdweb/views/view.haml +2 -2
- data/lib/milkode/common/util.rb +10 -2
- data/lib/milkode/database/document_table.rb +12 -0
- data/lib/milkode/grep/cli_grep.rb +25 -6
- data/milkode.gemspec +8 -2
- data/test/data/a_project/empty.txt +0 -0
- data/test/test_cdweb_app.rb +73 -0
- data/test/test_query.rb +25 -0
- data/test/test_util.rb +18 -0
- metadata +22 -5
@@ -16,6 +16,8 @@ module Milkode
|
|
16
16
|
['package', 'p'],
|
17
17
|
['filepath', 'fpath', 'f'],
|
18
18
|
['suffix', 's'],
|
19
|
+
['fp'], # fpath or package
|
20
|
+
['keyword', 'k'],
|
19
21
|
]
|
20
22
|
|
21
23
|
def initialize(str)
|
@@ -29,7 +31,7 @@ module Milkode
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def empty?
|
32
|
-
keywords.size == 0 && packages.size == 0 && fpaths.size == 0 && suffixs.size == 0
|
34
|
+
keywords.size == 0 && packages.size == 0 && fpaths.size == 0 && suffixs.size == 0 && fpath_or_packages.size == 0
|
33
35
|
end
|
34
36
|
|
35
37
|
def keywords
|
@@ -48,6 +50,39 @@ module Milkode
|
|
48
50
|
calc_param(2)
|
49
51
|
end
|
50
52
|
|
53
|
+
def fpath_or_packages
|
54
|
+
calc_param(3)
|
55
|
+
end
|
56
|
+
|
57
|
+
def multi_match_keywords
|
58
|
+
# 本当はkeywordsにしたかった・・
|
59
|
+
calc_param(4)
|
60
|
+
end
|
61
|
+
|
62
|
+
def conv_keywords_to_fpath
|
63
|
+
s = query_string.split.map {|v|
|
64
|
+
if keywords.include? v
|
65
|
+
"f:#{v}"
|
66
|
+
else
|
67
|
+
v
|
68
|
+
end
|
69
|
+
}.join(' ')
|
70
|
+
|
71
|
+
Query.new(s)
|
72
|
+
end
|
73
|
+
|
74
|
+
def conv_keywords_to_fpath_or_packages
|
75
|
+
s = query_string.split.map {|v|
|
76
|
+
if keywords.include? v
|
77
|
+
"fp:#{v}"
|
78
|
+
else
|
79
|
+
v
|
80
|
+
end
|
81
|
+
}.join(' ')
|
82
|
+
|
83
|
+
Query.new(s)
|
84
|
+
end
|
85
|
+
|
51
86
|
private
|
52
87
|
|
53
88
|
def calc_param(index)
|
@@ -20,11 +20,9 @@ module Milkode
|
|
20
20
|
LIMIT_NUM = 50 # 最大検索ファイル数
|
21
21
|
NTH = 3 # 表示範囲
|
22
22
|
COL_LIMIT = 200 # 1行の桁制限
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# NTH = 3 # 表示範囲
|
27
|
-
# COL_LIMIT = 200 # 1行の桁制限
|
23
|
+
|
24
|
+
MATH_FILE_DISP = 3 # マッチファイルの最大表示数
|
25
|
+
MATH_FILE_LIMIT = MATH_FILE_DISP + 1 # マッチファイルの検索リミット数
|
28
26
|
|
29
27
|
def initialize(path, params, query)
|
30
28
|
@path = path
|
@@ -33,8 +31,24 @@ module Milkode
|
|
33
31
|
@page = params[:page].to_i || 0
|
34
32
|
@offset = params[:offset].to_i
|
35
33
|
@line = params[:line].to_i
|
36
|
-
@is_onematch = params[:onematch]
|
37
|
-
@
|
34
|
+
@is_onematch = params[:onematch] == 'on'
|
35
|
+
@is_sensitive = params[:sensitive] == 'on'
|
36
|
+
|
37
|
+
# メインの検索
|
38
|
+
@records, @total_records, @elapsed = Database.instance.search(@q.keywords, @q.multi_match_keywords, @q.packages, path, @q.fpaths, @q.suffixs, @q.fpath_or_packages, @offset, LIMIT_NUM)
|
39
|
+
|
40
|
+
# マッチするファイル
|
41
|
+
@match_files = []
|
42
|
+
if @offset == 0 && @line == 0
|
43
|
+
t = 0
|
44
|
+
|
45
|
+
if (@path != "")
|
46
|
+
@match_files, t, @elapsed = 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
|
+
else
|
48
|
+
@match_files, t, @elapsed = 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
|
+
end
|
50
|
+
end
|
51
|
+
|
38
52
|
grep_contents
|
39
53
|
end
|
40
54
|
|
@@ -70,7 +84,28 @@ module Milkode
|
|
70
84
|
# g << [m]
|
71
85
|
end
|
72
86
|
|
73
|
-
|
87
|
+
<<EOF
|
88
|
+
#{match_files_contents}
|
89
|
+
#{match_groups.map{|g|result_match_record(g)}.join}
|
90
|
+
EOF
|
91
|
+
end
|
92
|
+
|
93
|
+
def match_files_contents
|
94
|
+
unless @match_files.empty?
|
95
|
+
is_and_more = @match_files.size >= MATH_FILE_LIMIT
|
96
|
+
@match_files = @match_files[0..MATH_FILE_DISP-1]
|
97
|
+
conv_query = (@path != "") ? @q.conv_keywords_to_fpath : @q.conv_keywords_to_fpath_or_packages
|
98
|
+
tmpp = @params.clone
|
99
|
+
tmpp[:query] = conv_query.query_string
|
100
|
+
url = Mkurl.new(@path, tmpp).inherit_query_shead
|
101
|
+
<<EOF
|
102
|
+
#{@match_files.map {|record| result_record(DocumentRecord.new(record))}.join}
|
103
|
+
#{"<a href='#{url}'>...and more</a></a>" if is_and_more}
|
104
|
+
<hr>
|
105
|
+
EOF
|
106
|
+
else
|
107
|
+
""
|
108
|
+
end
|
74
109
|
end
|
75
110
|
|
76
111
|
def html_pagination
|
@@ -78,7 +113,7 @@ module Milkode
|
|
78
113
|
return "" if next_offset >= @total_records
|
79
114
|
|
80
115
|
return <<EOF
|
81
|
-
<div class='pagination'>
|
116
|
+
<div class='pagination pagination-centered'>
|
82
117
|
#{pagination_link(next_offset, @next_line, "next >>")}
|
83
118
|
</div>
|
84
119
|
EOF
|
@@ -102,7 +137,7 @@ EOF
|
|
102
137
|
|
103
138
|
if @is_onematch
|
104
139
|
grep = Grep.new(record.content)
|
105
|
-
match_line = grep.one_match_and(@q.keywords)
|
140
|
+
match_line = grep.one_match_and(@q.keywords, @is_sensitive)
|
106
141
|
@match_records << MatchRecord.new(record, match_line) if match_line
|
107
142
|
|
108
143
|
if @match_records.size >= DISP_NUM
|
@@ -127,7 +162,7 @@ EOF
|
|
127
162
|
|
128
163
|
def grep_match_lines_stopover(record, index)
|
129
164
|
grep = Grep.new(record.content)
|
130
|
-
r = grep.match_lines_stopover(@q.keywords, DISP_NUM - @match_records.size, (index == 0) ? @line : 0)
|
165
|
+
r = grep.match_lines_stopover(@q.keywords, DISP_NUM - @match_records.size, (index == 0) ? @line : 0, @is_sensitive)
|
131
166
|
|
132
167
|
r[:result].each do |match_line|
|
133
168
|
@match_records << MatchRecord.new(record, match_line) if match_line
|
@@ -170,7 +205,7 @@ EOS
|
|
170
205
|
end
|
171
206
|
|
172
207
|
def pagination_link(offset, line, label)
|
173
|
-
tmpp = @params
|
208
|
+
tmpp = @params.clone
|
174
209
|
tmpp[:offset] = offset.to_s
|
175
210
|
tmpp[:line] = line.to_s
|
176
211
|
href = Mkurl.new("", tmpp).inherit_query_shead_offset
|
@@ -178,7 +213,13 @@ EOS
|
|
178
213
|
end
|
179
214
|
|
180
215
|
def pagination_span(content)
|
181
|
-
"<
|
216
|
+
"<ul><li>#{content}</li></ul>\n"
|
217
|
+
end
|
218
|
+
|
219
|
+
def result_record(record)
|
220
|
+
<<EOS
|
221
|
+
<dt class='result-file'>#{file_or_dirimg(true)}<a href='#{"/home/" + record_link(record)}'>#{Util::relative_path record.shortpath, @path}</a></dt>
|
222
|
+
EOS
|
182
223
|
end
|
183
224
|
|
184
225
|
def record_link(record) #
|
@@ -27,7 +27,7 @@ module Milkode
|
|
27
27
|
if (@q.fpaths.include?("*"))
|
28
28
|
@records, @total_records = Database.instance.selectAll(@offset, DISP_NUM)
|
29
29
|
else
|
30
|
-
@records, @total_records = Database.instance.search(@q.keywords, @q.packages, path, @q.fpaths, @q.suffixs, @offset, DISP_NUM)
|
30
|
+
@records, @total_records = Database.instance.search(@q.keywords, @q.multi_match_keywords, @q.packages, path, @q.fpaths, @q.suffixs, @q.fpath_or_packages, @offset, DISP_NUM)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -49,10 +49,10 @@ module Milkode
|
|
49
49
|
|
50
50
|
def html_pagination
|
51
51
|
return "" if @q.empty?
|
52
|
-
return "" if
|
52
|
+
return "" if @total_records < DISP_NUM
|
53
53
|
|
54
54
|
return <<EOF
|
55
|
-
<div class='pagination'>
|
55
|
+
<div class='pagination pagination-centered'>
|
56
56
|
#{pagination_link(next_offset, "next >>")}
|
57
57
|
</div>
|
58
58
|
EOF
|
@@ -72,7 +72,7 @@ EOF
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def pagination_span(content)
|
75
|
-
"<
|
75
|
+
"<ul><li>#{content}</li></ul>\n"
|
76
76
|
end
|
77
77
|
|
78
78
|
def result_record(record)
|
@@ -0,0 +1,151 @@
|
|
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 SearchGotoLine
|
15
|
+
attr_reader :total_records
|
16
|
+
attr_reader :page
|
17
|
+
|
18
|
+
DISP_NUM = 20 # 1ページの表示数
|
19
|
+
LIMIT_NUM = 50 # 最大検索ファイル数
|
20
|
+
NTH = 3 # 表示範囲
|
21
|
+
COL_LIMIT = 200 # 1行の桁制限
|
22
|
+
|
23
|
+
MATH_FILE_DISP = 3 # マッチファイルの最大表示数
|
24
|
+
MATH_FILE_LIMIT = MATH_FILE_DISP + 1 # マッチファイルの検索リミット数
|
25
|
+
|
26
|
+
def initialize(path, params, query)
|
27
|
+
@path = path
|
28
|
+
@params = params
|
29
|
+
@q = query
|
30
|
+
@page = params[:page].to_i || 0
|
31
|
+
@offset = params[:offset].to_i
|
32
|
+
|
33
|
+
# 検索クエリを解析
|
34
|
+
@gotolines = Util::parse_gotoline(@q.keywords)
|
35
|
+
|
36
|
+
# レコードをピックアップ
|
37
|
+
@records = []
|
38
|
+
@gotolines.each do |v|
|
39
|
+
@records << Database.instance.record(v[0][0][1..-1])
|
40
|
+
end
|
41
|
+
@total_records = @records.size
|
42
|
+
|
43
|
+
# 検索結果を表示
|
44
|
+
grep_contents
|
45
|
+
end
|
46
|
+
|
47
|
+
def query
|
48
|
+
@q.query_string
|
49
|
+
end
|
50
|
+
|
51
|
+
def next_offset
|
52
|
+
@offset + @next_index
|
53
|
+
end
|
54
|
+
|
55
|
+
def data_range
|
56
|
+
@offset..(@offset + @end_index)
|
57
|
+
end
|
58
|
+
|
59
|
+
def html_contents
|
60
|
+
match_groups = @match_records.reduce([]) do |g, m|
|
61
|
+
# 近接マッチ無効
|
62
|
+
g << [m]
|
63
|
+
end
|
64
|
+
|
65
|
+
<<EOF
|
66
|
+
#{match_groups.map{|g|result_match_record(g)}.join}
|
67
|
+
EOF
|
68
|
+
end
|
69
|
+
|
70
|
+
def html_pagination
|
71
|
+
return "" if @q.empty?
|
72
|
+
return "" if next_offset >= @total_records
|
73
|
+
|
74
|
+
return <<EOF
|
75
|
+
<div class='pagination pagination-centered'>
|
76
|
+
#{pagination_link(next_offset, @next_line, "next >>")}
|
77
|
+
</div>
|
78
|
+
EOF
|
79
|
+
end
|
80
|
+
|
81
|
+
def match_num
|
82
|
+
@match_records.size
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
MatchRecord = Struct.new(:record, :match_line)
|
88
|
+
|
89
|
+
def grep_contents
|
90
|
+
@match_records = []
|
91
|
+
@end_index = @next_index = @records.size
|
92
|
+
@next_line = nil
|
93
|
+
|
94
|
+
@records.each_with_index do |record, index|
|
95
|
+
@match_records << MatchRecord.new(record, Grep::MatchLineResult.new(@gotolines[index][1] - 1, nil))
|
96
|
+
|
97
|
+
if @match_records.size >= DISP_NUM
|
98
|
+
@end_index = index
|
99
|
+
@next_index = index + 1
|
100
|
+
break
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def result_match_record(match_group)
|
106
|
+
record = match_group[0].record
|
107
|
+
|
108
|
+
first_index = match_group[0].match_line.index - NTH
|
109
|
+
last_index = match_group[-1].match_line.index + NTH
|
110
|
+
match_lines = match_group.map{|m| m.match_line}
|
111
|
+
|
112
|
+
coderay = CodeRayWrapper.new(record.content, record.shortpath, match_lines)
|
113
|
+
coderay.col_limit(COL_LIMIT)
|
114
|
+
coderay.set_range(first_index..last_index)
|
115
|
+
|
116
|
+
url = "/home/" + record_link(record)
|
117
|
+
|
118
|
+
<<EOS
|
119
|
+
<dt class='result-record'><a href='#{url + "#n#{coderay.line_number_start}"}'>#{Util::relative_path record.shortpath, @path}</a></dt>
|
120
|
+
<dd>
|
121
|
+
#{coderay.to_html_anchorlink(url)}
|
122
|
+
</dd>
|
123
|
+
EOS
|
124
|
+
end
|
125
|
+
|
126
|
+
def pagination_link(offset, line, label)
|
127
|
+
tmpp = @params.clone
|
128
|
+
tmpp[:offset] = offset.to_s
|
129
|
+
tmpp[:line] = line.to_s
|
130
|
+
href = Mkurl.new("", tmpp).inherit_query_shead_offset
|
131
|
+
pagination_span("<a href='#{href}' rel='next'>#{label}</a>")
|
132
|
+
end
|
133
|
+
|
134
|
+
def pagination_span(content)
|
135
|
+
"<ul><li>#{content}</li></ul>\n"
|
136
|
+
end
|
137
|
+
|
138
|
+
def result_record(record)
|
139
|
+
<<EOS
|
140
|
+
<dt class='result-file'>#{file_or_dirimg(true)}<a href='#{"/home/" + record_link(record)}'>#{Util::relative_path record.shortpath, @path}</a></dt>
|
141
|
+
EOS
|
142
|
+
end
|
143
|
+
|
144
|
+
def record_link(record) #
|
145
|
+
Mkurl.new(record.shortpath, @params).inherit_query_shead
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
|
@@ -8,3 +8,27 @@
|
|
8
8
|
.anchor-table td { border: 1px solid silver; font-size:13px; }
|
9
9
|
.anchor-table a { color: #000000; text-decoration:none; }
|
10
10
|
.anchor-table a:hover { text-decoration:underline; background-color: #F0F0F0; }
|
11
|
+
|
12
|
+
/* code */
|
13
|
+
.CodeRay .line-numbers { background-color: #F5F5F5; }
|
14
|
+
.CodeRay .line-numbers a { background-color: #F5F5F5 !important; }
|
15
|
+
|
16
|
+
table.CodeRay td {
|
17
|
+
padding-left: 2px;
|
18
|
+
padding-right: 2px;
|
19
|
+
}
|
20
|
+
|
21
|
+
.CodeRay .line-numbers pre {
|
22
|
+
border-style: none;
|
23
|
+
padding-left: 2px;
|
24
|
+
padding-right: 2px;
|
25
|
+
}
|
26
|
+
|
27
|
+
td.code pre {
|
28
|
+
background-color: #ffffff;
|
29
|
+
white-space: pre;
|
30
|
+
word-wrap: normal;
|
31
|
+
overflow: auto;
|
32
|
+
}
|
33
|
+
|
34
|
+
|
@@ -8,8 +8,10 @@ div.footer {
|
|
8
8
|
}
|
9
9
|
|
10
10
|
div.search-summary {
|
11
|
-
border-color: #e92926;
|
12
|
-
background-color:#FFF0F0;
|
11
|
+
/* border-color: #e92926; */
|
12
|
+
/* background-color:#FFF0F0; */
|
13
|
+
border-color: #C0C0C0;
|
14
|
+
background-color: #FAFAFA;
|
13
15
|
border-top-style:solid;
|
14
16
|
border-top-width:1px;
|
15
17
|
border-bottom-style:solid;
|
@@ -30,11 +32,13 @@ dt.result-file {
|
|
30
32
|
}
|
31
33
|
|
32
34
|
div.pagination {
|
33
|
-
border-color: #e92926;
|
34
|
-
background-color:#FFF0F0;
|
35
|
+
/* border-color: #e92926; */
|
36
|
+
/* background-color:#FFF0F0; */
|
37
|
+
border-color: #C0C0C0;
|
38
|
+
background-color: #FBFBFB;
|
35
39
|
border-top-style:solid;
|
36
40
|
border-top-width:1px;
|
37
|
-
text-align: center;
|
41
|
+
/* text-align: center; */
|
38
42
|
margin-bottom: 20px;
|
39
43
|
}
|
40
44
|
|
@@ -89,6 +93,14 @@ ul.unstyled_margin {
|
|
89
93
|
margin-left: 7px;
|
90
94
|
}
|
91
95
|
|
96
|
+
select#shead {
|
97
|
+
width: 120px;
|
98
|
+
}
|
99
|
+
|
100
|
+
select#package {
|
101
|
+
width: 160px;
|
102
|
+
}
|
103
|
+
|
92
104
|
/* toppage */
|
93
105
|
|
94
106
|
#toppage {
|
@@ -123,3 +135,25 @@ ul.unstyled_margin {
|
|
123
135
|
#toppage .footer {
|
124
136
|
}
|
125
137
|
|
138
|
+
/* mainpage */
|
139
|
+
|
140
|
+
#mainpage {
|
141
|
+
margin-left: 20px;
|
142
|
+
margin-right: 20px;
|
143
|
+
font-size: 14px;
|
144
|
+
}
|
145
|
+
|
146
|
+
#mainpage .header {
|
147
|
+
margin-top: 20px;
|
148
|
+
}
|
149
|
+
|
150
|
+
#mainpage .search_form {
|
151
|
+
margin-top: 15px;
|
152
|
+
}
|
153
|
+
|
154
|
+
/* mainpage - help */
|
155
|
+
|
156
|
+
#mainpage .sample-code {
|
157
|
+
margin-top: 20px;
|
158
|
+
}
|
159
|
+
|