Lately, I’ve been experimenting with using Rake as a normal library in
regular Ruby scripts (rather than in Rakefiles). It turns out there
are some very useful things you can do.
For example, to locate a particular piece of code in a not so small
Ruby project, I often use the following command line:
This quickly searches all my Ruby files and displays matching lines
with file names and line numbers. However, the line is long to type
and won’t work in windows (unless you have cygwin installed).
So I wrote the following Ruby program and saved it in a file called “fic” (Find In Code):
This proved so useful, that I enhanced the code to allow for searching
for files ending in arbitrary extendsions and to handle more matching
options on the command line.
Here’s the enhanced version:
#!/usr/bin/env ruby
# -*- ruby -*-
exts = ['.rb']
if ARGV[0] =~ /^\.[a-zA-Z0-9]+$/
exts = []
while ARGV[0] =~ /^\.[a-zA-Z0-9]+$/
exts << ARGV.shift
end
end
ext = "{" + exts.join(',') + "}"
if ARGV.size < 1
puts "Usage: #{File.basename($0)} [.ext ...] pattern ..."
exit 1
end
require 'rake'
FileList["**/*#{ext}"].egrep(Regexp.new(ARGV.join('|')))
And if you are using Emacs …
If you are using Emacs, and you have my “visit source” code loaded,
all you need to do is put the cursor on the line you are interested in
and press F2.
Oh, you would like to see the elisp code for “visit source”? Let’s
see, where did I put that?
Now, I move the cursor to the first line and press F2, and I find:
;;; Source File Visiting =============================================
(defun jw-current-line ()
"Return the current line."
(let
((bol (save-excursion (beginning-of-line)(point)))
(eol (save-excursion (end-of-line)(point))))
(buffer-substring bol eol) ))
(defun jw-extract-file-lines (line)
"Extract a list of file/line pairs from the given line of text."
(let*
((unix_fn "[^ \t\n\r\"'([<{]+")
(dos_fn "[a-zA-Z]:[^\t\n\r\"'([<{]+")
(flre (concat "\\(" unix_fn "\\|" dos_fn "\\):\\([0-9]+\\)"))
(start nil)
(result nil))
(while (string-match flre line start)
(setq start (match-end 0))
(setq result
(cons (list
(substring line (match-beginning 1) (match-end 1))
(string-to-int (substring line (match-beginning 2) (match-end 2))))
result)))
result))
(defun jw-select-file-line (candidates)
"Select a file/line candidate that references an existing file."
(cond ((null candidates) nil)
((file-readable-p (caar candidates)) (car candidates))
(t (jw-select-file-line (cdr candidates))) ))
(defun jw-visit-source ()
"If the current line contains text like '../src/program.rb:34', visit
that file in the other window and position point on that line."
(interactive)
(let* ((line (jw-current-line))
(candidates (jw-extract-file-lines line))
(file-line (jw-select-file-line candidates)))
(cond (file-line
(find-file-other-window (car file-line))
(goto-line (cadr file-line)) )
(t
(error "No source location on line.")) )))