Skip to content

Instantly share code, notes, and snippets.

Created May 30, 2009 12:12
Show Gist options
  • Save anonymous/120482 to your computer and use it in GitHub Desktop.
Save anonymous/120482 to your computer and use it in GitHub Desktop.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>changed</key>
<dict>
<key>command</key>
<string>#!/usr/bin/env ruby -rcgi
# By Henrik Nyh &lt;http://henrik.nyh.se&gt; 2007-06-26
# Free to modify and redistribute with credit.
%w{ui web_preview escape}.each { |lib| require "%s/lib/%s" % [ENV['TM_SUPPORT_PATH'], lib] }
NAME = "Grep in Project"
HEAD = &lt;&lt;-HTML
&lt;style type="text/css"&gt;
table { font-size:0.9em; border-collapse:collapse; border-bottom:1px solid #555; }
h2 { font-size:1.3em; }
tr { background:#FFF; }
tr.odd { background:#EEE; }
td { vertical-align:top; white-space:nowrap; padding:0.4em 1em; color:#000 !important; }
tr td:first-child { text-align:right; padding-right:1.5em; }
td a { color:#00F !important; }
tr.binary { background:#E8AFA8; }
tr.binary.odd { background:#E0A7A2; }
tr#empty { border-bottom:1px solid #FFF; }
tr#empty td { text-align:center; }
tr.newFile, tr.binary { border-top:1px solid #555; }
.keyword { font-weight:bold; background:#F6D73A; margin:0 0.1em; }
.ellipsis { color:#777; margin:0 0.5em; }
&lt;/style&gt;
&lt;script type="text/javascript"&gt;
function reveal_file(path) {
const quote = '"';
const command = "osascript -e ' tell app "+quote+"Finder"+quote+"' " +
" -e 'reveal (POSIX file " +quote+path+quote + ")' " +
" -e 'activate' " +
" -e 'end' ";
TextMate.system(command, null);
}
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
curtop += obj.offsetTop
}
}
return {left: curleft, top: curtop};
}
function resizeTableToFit() {
var table = document.getElementsByTagName("table")[0];
const minWidth = 450, minHeight = 250;
var pos = findPos(table);
var tableFitWidth = table.offsetWidth + pos.left * 2;
var tableFitHeight = table.offsetHeight + pos.top + 50;
var screenFitWidth = screen.width - 150;
var screenFitHeight = screen.height - 150;
var setWidth = tableFitWidth &gt; screenFitWidth ? screenFitWidth : tableFitWidth;
var setHeight = tableFitHeight &gt; screenFitHeight ? screenFitHeight : tableFitHeight;
setWidth = setWidth &lt; minWidth ? minWidth : setWidth;
setHeight = setHeight &lt; minHeight ? minHeight : setHeight;
window.resizeTo(setWidth, setHeight);
}
&lt;/script&gt;
HTML
RESIZE_TABLE = &lt;&lt;-HTML
&lt;script type="text/javascript"&gt;
resizeTableToFit();
&lt;/script&gt;
HTML
def ellipsize_path(path)
path.sub(/^(.{30})(.{10,})(.{30})$/) { "#$1⋯#$3" }
end
def escape(string)
CGI.escapeHTML(string)
end
def bail(message)
puts &lt;&lt;-HTML
&lt;h2&gt;#{ message }&lt;/h2&gt;
HTML
html_footer
exit
end
directory = ENV['TM_PROJECT_DIRECTORY'] ||
( ENV['TM_FILEPATH'] &amp;&amp; File.dirname(ENV['TM_FILEPATH']) )
puts html_head(
:window_title =&gt; NAME,
:page_title =&gt; NAME,
:sub_title =&gt; directory || "Error",
:html_head =&gt; HEAD
)
bail("Not in a saved file") unless directory
query = TextMate::UI.request_string(:title =&gt; "Grep in Project", :prompt =&gt; "Find this:", :default =&gt; %x{pbpaste -pboard find})
bail("Search aborted") unless query
IO.popen('pbcopy -pboard find', 'w') { |copy| copy.print query }
puts &lt;&lt;-HTML
&lt;h2&gt;Searching for “#{ escape(query) }”&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;(excluding /vendor, /.svn, and /.git directories and .log files)&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
HTML
# TODO: Respect ENV['TM_SELECTED_FILES']
command = %{cd "#{directory}"; find . \\( -path '*/.svn' -or -path '*/.git' -or -path '*/vendor' \\) -prune -or -type f -print0 | xargs -0 grep -nr --ignore-case --fixed-strings --exclude='*.log' #{e_sh query}}
IO.popen(command) do |pipe|
# Used to highlight matches
query_re = Regexp.new( Regexp.escape(CGI.escapeHTML(query)), Regexp::IGNORECASE)
last_path = path = i = nil
pipe.each_with_index do |line, i|
if line =~ /^(Binary file )(.*?) matches/
prefix, file = $1, $2
path = directory + file[1..-1]
puts &lt;&lt;-HTML
&lt;tr class="binary #{ 'odd' unless i%2==0 }"&gt;
&lt;td&gt;
#{ prefix }
&lt;a href="javascript:reveal_file('#{ escape(path) }')" title="#{ escape(path) }"&gt;#{ ellipsize_path(file) }&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
#{ RESIZE_TABLE if i%100==0 }
HTML
next
end
line.gsub!(/^([^:]+):(\d+):(.*)$/) do
relative_path, line_number, content = $1, $2, $3.strip
path = directory + relative_path[1..-1]
url = "txmt://open/?url=file://#{path}&amp;line=#{line_number}"
content = escape(content).
# Highlight keywords
gsub(query_re) { %{&lt;strong class="keyword"&gt;#$&amp;&lt;/strong&gt;} }.
# Ellipsize before, between and after keywords
gsub(%r{(^[^&lt;]{25}|&lt;/strong&gt;[^&lt;]{15})([^&lt;]{20,})([^&lt;]{15}&lt;strong|[^&lt;]{25}$)}) do
%{#$1&lt;span class="ellipsis" title="#{escape($2)}"&gt;⋯&lt;/span&gt;#$3}
end
&lt;&lt;-HTML
&lt;tr class="#{ 'odd' unless i%2==0 } #{ 'newFile' if (path != last_path) }"&gt;
&lt;td&gt;
&lt;a href="#{ url }" title="#{ "%s:%s" % [path, line_number] }"&gt;
#{ "%s:%s" % [ellipsize_path(relative_path), line_number] }
&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;#{ content }&lt;/td&gt;
&lt;/tr&gt;
HTML
end
puts line
last_path = path
end
if i
# A paragraph inside the table ends up at the top even though it's output
# at the end. Something of a hack :)
i += 1
puts &lt;&lt;-HTML
&lt;p&gt;#{i} matching line#{i==1 ? '' : 's'}:&lt;/p&gt;
#{RESIZE_TABLE}
HTML
else
puts &lt;&lt;-HTML
&lt;tr id="empty"&gt;&lt;td colspan="2"&gt;No results.&lt;/td&gt;&lt;/tr&gt;
HTML
end
end
puts &lt;&lt;-HTML
&lt;/table&gt;
HTML
html_footer
</string>
</dict>
<key>deleted</key>
<array/>
<key>isDelta</key>
<true/>
<key>uuid</key>
<string>3B7E16C9-0D34-42D4-8431-06CB7D819655</string>
</dict>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment