milkode 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|