Permalink
Browse files

[ADDED] Real time filtering of result list and option to show file pa…

…ths relative to project directory

git-svn-id: http://svn.textmate.org/trunk/Bundles/TODO.tmbundle@11786 dfb7d73b-c2ec-0310-8fea-fb051d288c6d
  • Loading branch information...
1 parent a9ede5c commit ac07daa573e3c8063569350d08f5880c7380bb26 @Soryu Soryu committed Oct 18, 2009
Showing with 114 additions and 10 deletions.
  1. +9 −0 Support/css/default/style.css
  2. +6 −1 Support/template_head.rhtml
  3. +3 −3 Support/template_item.rhtml
  4. +80 −4 Support/template_tail.rhtml
  5. +16 −2 Support/todo.rb
@@ -70,6 +70,15 @@
padding: 2px;
}
+#todo_list .todo_hidden {
+ display: none;
+}
+
+/* TODO: alternate row bg colors don't work anymore with filtering */
+/*#todo_list table.todo_content tr[class=""]:nth-child(even) {
+ background-color: rgba(127,127,127,0.15);
+}*/
+
#toplink {
position: fixed;
bottom: 1em;
@@ -2,10 +2,15 @@
function goTo(id) {
document.body.scrollTop = document.getElementById(id).offsetTop + 8;
}
+ window["_todo"] = {};
+ window["_tags"] = [];
+ <% tags.each do |tag| %>
+ window["_tags"].push("<%= tag[:label] %>");
+ window["_todo"]["<%= tag[:label] %>"] = [];
+ <% end %>
</script>
<div id="todo_list">
-
<ul class="counters">
<% tags.each do |tag| %>
<li id="counter_tab_<%= tag[:label].sub(/\W/, '_') %>" class="bg_<%= tag[:label].sub(/\W/, '_') %>" <% if tag[:trim_if_empty] then %>style="display: none;"<% end %>><a onclick="goTo('jump_to_<%= tag[:label].sub(/\W/, '_') %>'); return false;" href="#jump_to_<%= tag[:label].sub(/\W/, '_') %>" accesskey="<%= tag[:label][0..0] %>"><%= tag[:label] %></a>: <span id="count_<%= tag[:label].sub(/\W/, '_') %>">0</span></li>
@@ -1,7 +1,7 @@
-<tr <% if count % 2 == 0 then %> class="alternate" <% end %>>
+<tr id="item_<%= tag[:label] %>_<%= match[:index] %>">
<td class="file">
- <a title="<%= html_escape(match[:content].strip) %>" href="<%= TextMate.file_link(match[:file], match[:line]) %>">
- <%= "#{html_escape(File.basename(match[:file]))}" %></a> (<%= match[:line] %>)
+ <a title="<%= html_escape(match[:content]) %>" href="<%= TextMate.file_link(match[:file], match[:line]) %>">
+ <span class="item_relative_path todo_hidden"><%= "#{html_escape(match[:file].sub(Regexp.new(project_dir+"/?"), ''))}" %></span><span class="item_filename"><%= "#{html_escape(File.basename(match[:file]))}" %></span></a> (<%= match[:line] %>)
</td>
<td class="comment">
<%= match[:match] %>
@@ -3,17 +3,93 @@
var box = document.getElementById("total_count");
box.innerHTML = "<%= total %>";
</script>
-
+
+ <fieldset>
+ <legend>Options</legend>
+ <label>Filter comment</label> <input type="text" value="" id="filter" size="40">
+ <label>Show relative paths</label> <input type="checkbox" id="trigger_relative_paths">
+ </fieldset>
+
<% tags.each do |tag| %>
<% next if tag[:matches].length == 0 %>
- <h3><a id="jump_to_<%= tag[:label] %>"><%= tag[:label] %></a></h3>
- <table class="sortable" id="table_<%= tag[:label] %>">
+
+ <% tag[:matches].each do |match| %>
+ <script type="text/javascript" charset="utf-8">
+ window["_todo"]["<%= tag[:label] %>"][<%= match[:index] %>] = "<%= html_escape(match[:clean]) %>";
+ </script>
+ <% end %>
+
+
+ <h3 id="heading_<%= tag[:label] %>"><a id="jump_to_<%= tag[:label] %>"><%= tag[:label] %></a></h3>
+ <table class="todo_content sortable" id="table_<%= tag[:label] %>">
<tr>
<th>File</th>
<th>Comment</th>
</tr>
- <%= tag[:rendered] %>
+
+ <% tag[:matches].each do |match| %>
+ <%= match[:rendered] %>
+ <% end %>
</table>
<% end %>
<a href="#todo_list" id="toplink">↑ top</a>
+ <div id="info_no_results" class="todo_hidden">None of the items matched your filter criteria.</div>
</div>
+<script type="text/javascript" charset="utf-8">
+ document.getElementById("filter").focus();
+ document.getElementById("filter").onkeyup = function(e) {
+ var counter_all = 0;
+ var filter = document.getElementById("filter").value;
+ for(var tag_key in window._tags)
+ {
+ var counter = 0;
+ var tag = window._tags[tag_key];
+ for (var i = window._todo[tag].length - 1; i >= 0; i--){
+ var match = window._todo[tag][i].toLowerCase();
+ if (!match) continue;
+ var res = match.indexOf(filter);
+ var element = document.getElementById("item_"+tag+"_"+i);
+ if (element)
+ element.className = ((res >= 0) ? '' : 'todo_hidden');
+ if (res >= 0)
+ counter++;
+ }
+ // Change counters accordingly
+ var id = tag.replace(/\W/, '_');
+ var element = document.getElementById("count_"+id)
+ if (element)
+ element.innerHTML = counter;
+ // Hide empty tables
+ var element = document.getElementById("table_"+id)
+ if (element)
+ {
+ var css_classes = element.className.split(" ");
+ var index = css_classes.indexOf("todo_hidden");
+ if (counter == 0 && index == -1)
+ css_classes.push("todo_hidden")
+ else if (counter > 0 && index >= 0)
+ css_classes = css_classes.slice(0, index).concat(css_classes.slice(index+1))
+ element.className = css_classes.join(" ");
+ }
+ var element = document.getElementById("heading_"+id)
+ if (element)
+ element.className = counter == 0 ? 'todo_hidden' : '';
+ counter_all += counter
+ }
+ document.getElementById("total_count").innerHTML = counter_all;
+ document.getElementById("info_no_results").className = counter_all > 0 ? 'todo_hidden' : '';
+ }
+ document.getElementById("trigger_relative_paths").onchange = function(e) {
+ var on = document.getElementById("trigger_relative_paths").checked;
+ var list = document.getElementsByClassName('item_filename');
+ for (var i = list.length - 1; i >= 0; i--){
+ var el = list[i];
+ el.className = "item_filename" + (on ? " todo_hidden" : "");
+ };
+ var list = document.getElementsByClassName('item_relative_path');
+ for (var i = list.length - 1; i >= 0; i--){
+ var el = list[i];
+ el.className = "item_relative_path" + (on ? "" : " todo_hidden");
+ };
+ }
+</script>
View
@@ -13,6 +13,14 @@
require "#{ENV['TM_SUPPORT_PATH']}/lib/web_preview"
+if ARGV.size > 0
+ if ARGV[0] == 'file'
+ ENV.delete 'TM_PROJECT_DIRECTORY'
+ elsif ARGV[0] == 'dir'
+ ENV['TM_PROJECT_DIRECTORY'] = File.dirname ENV['TM_FILEPATH']
+ end
+end
+
if ENV['TM_PROJECT_DIRECTORY'] == '/'
puts html_head(:window_title => "TODO", :page_title => "TODO List", :sub_title => "Error")
puts <<-HTML
@@ -57,6 +65,7 @@ def TextMate.file_link (file, line = 0)
STDOUT.flush
+project_dir = ENV['TM_PROJECT_DIRECTORY']
home_dir = /^#{Regexp.escape ENV['HOME']}/
total = 0
TextMate.each_text_file do |file|
@@ -70,19 +79,24 @@ def TextMate.file_link (file, line = 0)
:file => file,
:line => io.lineno,
:content => content,
- :type => tag[:label]
+ :type => tag[:label],
+ :rendered => '',
+ :index => tag[:matches].length
}
if tag[:label] == "RADAR" then
url, display = "http://openradar.appspot.com/" + $2, "rdar://" + $2
match[:match] = html_escape($1) + "<a href=\"" + url + "\" target=\"_blank\">" + html_escape(display) + "</a>" + html_escape($3)
else
match[:match] = html_escape($1)
end
+ match[:clean] = match[:content].gsub(/\s+/, " ").gsub(/[^\w@`~!@#\$%\^&*\(\)-=+\[\]|\\\'\"\{\}<>,.\/\? ]/i, "")
+
tag[:matches] << match
count = tag[:matches].length
total += 1
puts ERB.new(File.read("#{ENV['TM_BUNDLE_SUPPORT']}/template_update.rhtml"), 0, '<>').result(binding)
- tag[:rendered] += ERB.new(File.read("#{ENV['TM_BUNDLE_SUPPORT']}/template_item.rhtml"), 0, '<>').result binding
+ match[:rendered] = ERB.new(File.read("#{ENV['TM_BUNDLE_SUPPORT']}/template_item.rhtml"), 0, '<>').result binding
+ tag[:rendered] += match[:rendered]
STDOUT.flush
end
end if File.readable?(file)

0 comments on commit ac07daa

Please sign in to comment.