redcar-dev 0.12.15dev-java → 0.12.16dev-java
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/CHANGES +3 -0
- data/lib/redcar.rb +1 -1
- data/plugins/application/lib/application/dialogs/filter_list_dialog.rb +26 -16
- data/plugins/project_search/lib/project_search/lucene_index.rb +11 -11
- data/plugins/project_search/lib/project_search/stylesheets/style.css +3 -2
- data/plugins/project_search/lib/project_search/views/_file.html.erb +6 -6
- data/plugins/project_search/lib/project_search/views/index.html.erb +6 -6
- data/plugins/project_search/lib/project_search/word_search.rb +28 -14
- metadata +2 -2
data/CHANGES
CHANGED
@@ -19,6 +19,9 @@ Version 0.12 (TBA)
|
|
19
19
|
* Added option to add editable ComboItem widgets to Speedbars (Delisa Mason)
|
20
20
|
* Updated UI Styling (Delisa Mason)
|
21
21
|
* Added option to color tree background color via ApplicationSWT preferences (Delisa Mason)
|
22
|
+
* Project tree has colourful icons (Delisa Mason)
|
23
|
+
* Uses gems to install everything (Dan Lucraft)
|
24
|
+
* Wildcards permitted in project search (Delisa Mason)
|
22
25
|
|
23
26
|
Version 0.11 (23 March 2011)
|
24
27
|
============================
|
data/lib/redcar.rb
CHANGED
@@ -58,27 +58,37 @@ module Redcar
|
|
58
58
|
# @block A -> String optionally turns an element from the list into a string to match on
|
59
59
|
def filter_and_rank_by(list, query, max_length=20)
|
60
60
|
re = make_regex(query)
|
61
|
-
|
61
|
+
ranked_list = []
|
62
62
|
cutoff = 100000000
|
63
63
|
results = list.each do |element|
|
64
|
-
bit = block_given? ? yield(element) : element
|
65
64
|
begin
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
match_data = (block_given? ? yield(element) : element).match(re)
|
66
|
+
if match_data
|
67
|
+
captures = []
|
68
|
+
match_data.captures.each_with_index do |_, i|
|
69
|
+
i += 1 # Match group 0 is actually the complete regex, we are interested in the subgroups
|
70
|
+
previous_capture = captures.last
|
71
|
+
if previous_capture and match_data.begin(i) - previous_capture[:end] <= 1
|
72
|
+
# If the the current match starts where the previous match ended, or they even overlap, merge the matches
|
73
|
+
captures.last[:end] = match_data.end(i)
|
72
74
|
else
|
73
|
-
|
75
|
+
# Record the match
|
76
|
+
captures << {:begin => match_data.begin(i), :end => match_data.end(i)}
|
74
77
|
end
|
75
78
|
end
|
76
|
-
if
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
79
|
+
if captures.first[:begin] < cutoff
|
80
|
+
# The penalty is calculated as such: The values of the beginnings of matches are penalty, the lengths are bonuses
|
81
|
+
# This way, matching early and continiously is rewarded. Matching late in a word or only at intervals is punished.
|
82
|
+
penalty = captures.inject(0) {|p,c| p + c[:begin] - (c[:end] - c[:begin]) }
|
83
|
+
ranked_list << {:penalty => penalty, :first_match => captures.first[:begin], :element => element}
|
84
|
+
ranked_list = ranked_list.sort_by {|a| a[:penalty] }
|
85
|
+
|
86
|
+
# Performance optimization: Once we reach the maximum length, remove elements (saves later sorting)
|
87
|
+
# Set the new cutoff to the beginning of the previously last element, to avoid later elements getting
|
88
|
+
# into the list which would have an even worse rank.
|
89
|
+
if ranked_list.length > max_length
|
90
|
+
cutoff = ranked_list.last[:first_match]
|
91
|
+
ranked_list.pop
|
82
92
|
end
|
83
93
|
end
|
84
94
|
end
|
@@ -88,7 +98,7 @@ module Redcar
|
|
88
98
|
# unicode in them.
|
89
99
|
end
|
90
100
|
end
|
91
|
-
|
101
|
+
ranked_list.map {|a| a[:element] }
|
92
102
|
end
|
93
103
|
|
94
104
|
# The time interval in seconds in which moved_to events are ignored
|
@@ -2,27 +2,27 @@
|
|
2
2
|
class ProjectSearch
|
3
3
|
class LuceneIndex
|
4
4
|
attr_accessor :last_updated, :lucene_index
|
5
|
-
|
5
|
+
|
6
6
|
def initialize(project)
|
7
7
|
@project = project
|
8
8
|
@has_content = false
|
9
9
|
load
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def timestamp_file_path
|
13
13
|
File.join(@project.config_dir, 'lucene_last_updated')
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def lucene_index_dir
|
17
17
|
File.join(@project.config_dir, "lucene")
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def delete
|
21
21
|
FileUtils.rm(timestamp_file_path)
|
22
22
|
FileUtils.rm_r(lucene_index_dir)
|
23
23
|
load
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def load
|
27
27
|
@last_updated = Time.at(0)
|
28
28
|
if File.exist?(timestamp_file_path)
|
@@ -30,19 +30,19 @@ class ProjectSearch
|
|
30
30
|
@has_content = true
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def dump
|
35
35
|
File.open(timestamp_file_path, "w") do |fout|
|
36
36
|
fout.puts(last_updated.to_i.to_s)
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def has_content?
|
41
41
|
@has_content
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
MAX_FILE_SIZE = 500 * 1024
|
45
|
-
|
45
|
+
|
46
46
|
def update
|
47
47
|
changed_files = @project.file_list.changed_since(last_updated)
|
48
48
|
@last_updated = Time.now
|
@@ -60,7 +60,7 @@ class ProjectSearch
|
|
60
60
|
pre_contents = File.new(fn).read(200)
|
61
61
|
unless !pre_contents or BinaryDataDetector.binary?(pre_contents)
|
62
62
|
contents = File.read(fn)
|
63
|
-
adjusted_contents = contents
|
63
|
+
adjusted_contents = contents.gsub(/\.([^\s])/, '. \1')
|
64
64
|
@lucene_index << { :id => fn, :contents => adjusted_contents }
|
65
65
|
end
|
66
66
|
rescue => e
|
@@ -76,6 +76,6 @@ class ProjectSearch
|
|
76
76
|
end
|
77
77
|
dump
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
end
|
81
81
|
end
|
@@ -2,7 +2,8 @@
|
|
2
2
|
margin: 0;
|
3
3
|
padding: 0;
|
4
4
|
font-weight: normal;
|
5
|
-
font-
|
5
|
+
font-size: 14px;
|
6
|
+
font-family: Myriad, Helvetica Neue, Sawasdee, Lucida Grande, sans-serif;
|
6
7
|
}
|
7
8
|
|
8
9
|
body {
|
@@ -167,7 +168,7 @@ body {
|
|
167
168
|
/* background-color: #ccc;*/
|
168
169
|
padding: 4px 4px 4px 12px;
|
169
170
|
font-weight: bold;
|
170
|
-
font-family:Helvetica Neue, Sawasdee, sans-serif;
|
171
|
+
font-family: Myriad, Helvetica Neue, Sawasdee, Lucida Grande, sans-serif;
|
171
172
|
border-bottom: 1px dotted #aaa;
|
172
173
|
}
|
173
174
|
|
@@ -27,8 +27,8 @@
|
|
27
27
|
<% line_index += 1 %>
|
28
28
|
<tr class="result file_<%= file_num %> line_<%= this_line_num %> <%= (line_index % 2 == 0 ? 'even' : 'odd') %>" data-href='<%= CGI::escapeHTML(file) %>' data-line_num='<%= this_line_num %>'>
|
29
29
|
<td class='line_num'><%= this_line_num %></td>
|
30
|
-
<% text = CGI.escapeHTML(context_line
|
31
|
-
<td class='text'><pre><%= text.chomp + " " %></pre></td> <!-- extra space to ensure line-height is respected -->
|
30
|
+
<% text = CGI.escapeHTML(context_line.gsub(@word_search.regex) { "__span__#{$&}__span__" }) %>
|
31
|
+
<td class='text'><pre><%= text.gsub(/__span__(.*?)__span__/,"<span>\\1</span>").chomp + " " %></pre></td> <!-- extra space to ensure line-height is respected -->
|
32
32
|
</tr>
|
33
33
|
<% end %>
|
34
34
|
<% end %>
|
@@ -37,8 +37,8 @@
|
|
37
37
|
<% last_displayed_line_num = display_line_num %>
|
38
38
|
<tr class="result file_<%= file_num %> line_<%= display_line_num %> <%= (line_index % 2 == 0 ? 'even' : 'odd') %>" data-href='<%= CGI::escapeHTML(file) %>' data-line_num='<%= display_line_num %>'>
|
39
39
|
<td class='line_num'><%= display_line_num %></td>
|
40
|
-
<% text = CGI.escapeHTML(hit.line
|
41
|
-
<td class='text'><pre><%= text.chomp + " " %></pre></td> <!-- extra space to ensure line-height is respected -->
|
40
|
+
<% text = CGI.escapeHTML(hit.line.gsub(@word_search.regex) { "__span__#{$&}__span__" }) %>
|
41
|
+
<td class='text'><pre><%= text.gsub(/__span__(.*?)__span__/,"<span>\\1</span>").chomp + " " %></pre></td> <!-- extra space to ensure line-height is respected -->
|
42
42
|
</tr>
|
43
43
|
|
44
44
|
<% hit.post_context.each_with_index do |context_line, i| %>
|
@@ -48,8 +48,8 @@
|
|
48
48
|
<% line_index += 1 %>
|
49
49
|
<tr class="result file_<%= file_num %> line_<%= this_line_num %> <%= (line_index % 2 == 0 ? 'even' : 'odd') %>" data-href='<%= CGI::escapeHTML(file) %>' data-line_num='<%= this_line_num %>'>
|
50
50
|
<td class='line_num'><%= this_line_num %></td>
|
51
|
-
<% text = CGI.escapeHTML(context_line
|
52
|
-
<td class='text'><pre><%= text.chomp + " " %></pre></td> <!-- extra space to ensure line-height is respected -->
|
51
|
+
<% text = CGI.escapeHTML(context_line.gsub(@word_search.regex) { "__span__#{$&}__span__" }) %>
|
52
|
+
<td class='text'><pre><%= text.gsub(/__span__(.*?)__span__/,"<span>\\1</span>").chomp + " " %></pre></td> <!-- extra space to ensure line-height is respected -->
|
53
53
|
</tr>
|
54
54
|
<% end %>
|
55
55
|
<% end %>
|
@@ -7,17 +7,17 @@
|
|
7
7
|
|
8
8
|
<% plugin_css = File.expand_path(File.join(plugin_root, %w(lib project_search stylesheets style.css))) %>
|
9
9
|
<style>
|
10
|
-
<% font_size =
|
10
|
+
<% font_size = 12 %>
|
11
11
|
#results .text pre, #results .text pre span, #query,#results .line_num, #recent_queries {
|
12
12
|
font-family: <%= Redcar::EditView.font %>;
|
13
|
-
font-size: <%= font_size
|
13
|
+
font-size: <%= font_size%>px;
|
14
14
|
}
|
15
15
|
#results .line_num {
|
16
|
-
font-size:<%= font_size -
|
17
|
-
line-height:<%= font_size -
|
16
|
+
font-size:<%= font_size - 2 %>px;
|
17
|
+
line-height:<%= font_size - 2 %>px;
|
18
18
|
}
|
19
19
|
#results .text pre {
|
20
|
-
font-size: <%= font_size -
|
20
|
+
font-size: <%= font_size - 1 %>px;
|
21
21
|
line-height: <%= font_size - 3 %>px;
|
22
22
|
}
|
23
23
|
</style>
|
@@ -147,7 +147,7 @@
|
|
147
147
|
|
148
148
|
$('.file_link').live('click',function() {
|
149
149
|
$('body').animate({
|
150
|
-
scrollTop: $("#"+$(this).attr('id').replace("link_","")).offset().top -
|
150
|
+
scrollTop: $("#"+$(this).attr('id').replace("link_","")).offset().top - 100
|
151
151
|
}, 0);
|
152
152
|
});
|
153
153
|
});
|
@@ -13,19 +13,19 @@ class ProjectSearch
|
|
13
13
|
@match_case = !!match_case
|
14
14
|
@context_size = context_size
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def match_case?
|
18
18
|
@match_case
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def context?
|
22
22
|
@context_size > 0
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def matching_line?(line)
|
26
26
|
line =~ regex
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def regex
|
30
30
|
@regex ||= begin
|
31
31
|
regexp_text = Regexp.escape(@query_string)
|
@@ -37,11 +37,11 @@ class ProjectSearch
|
|
37
37
|
match_case? ? /#{regexp_text}/ : /#{regexp_text}/i
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def on_file_results(&block)
|
42
42
|
@on_file_results_block = block
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def generate_results
|
46
46
|
hits = []
|
47
47
|
doc_ids.each do |doc_id|
|
@@ -58,9 +58,9 @@ class ProjectSearch
|
|
58
58
|
remove_hits << hit
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
hits_needing_post_context -= remove_hits
|
63
|
-
|
63
|
+
|
64
64
|
if matching_line?(line)
|
65
65
|
hit = Hit.new(doc_id, line_num, line, regex, pre_context.dup, [])
|
66
66
|
hits << hit
|
@@ -78,13 +78,13 @@ class ProjectSearch
|
|
78
78
|
end
|
79
79
|
hits
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
def send_file_results(hits)
|
83
83
|
if @on_file_results_block
|
84
84
|
@on_file_results_block.call(hits)
|
85
85
|
end
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
def results
|
89
89
|
@results ||= generate_results
|
90
90
|
end
|
@@ -95,18 +95,32 @@ class ProjectSearch
|
|
95
95
|
"contents",
|
96
96
|
StandardAnalyzer.new(Version::LUCENE_29)
|
97
97
|
)
|
98
|
-
|
98
|
+
begin
|
99
|
+
text = query_string.gsub(/^\W+/,"").gsub(/\(|\)/," ").strip
|
100
|
+
unless text.empty?
|
101
|
+
query = parser.parse(text)
|
102
|
+
return query.to_s.gsub("_*","*").gsub(/_|\./," ").strip
|
103
|
+
end
|
104
|
+
rescue => e
|
105
|
+
p e.message
|
106
|
+
p e.backtrace
|
107
|
+
end
|
108
|
+
return ""
|
99
109
|
end
|
100
110
|
|
101
111
|
def doc_ids
|
102
112
|
@doc_ids ||= begin
|
103
113
|
index = ProjectSearch.indexes[project.path].lucene_index
|
104
114
|
doc_ids = nil
|
105
|
-
|
106
|
-
|
115
|
+
if text = formatted_query and not text.empty?
|
116
|
+
doc_ids = index.find(text).map {|doc| doc.id}.uniq
|
117
|
+
doc_ids.reject {|doc_id| Redcar::Project::FileList.hide_file_path?(doc_id) }
|
118
|
+
else
|
119
|
+
[]
|
120
|
+
end
|
107
121
|
end
|
108
122
|
end
|
109
|
-
|
123
|
+
|
110
124
|
def ignore_regexes
|
111
125
|
self.class.shared_storage['ignored_file_patterns']
|
112
126
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: redcar-dev
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 7
|
5
|
-
version: 0.12.
|
5
|
+
version: 0.12.16dev
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Daniel Lucraft
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-20 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|