Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
132 lines (115 sloc) 4.94 KB
;;; rcov.el -- Ruby Coverage Analysis Tool
;;; Copyright (c) 2006 rubikitch <>
;;; Use and distribution subject to the terms of the rcov license.
(defvar rcov-xref-before-visit-source-hook nil
"Hook executed before jump.")
(defvar rcov-xref-after-visit-source-hook nil
"Hook executed after jump.")
(defvar rcov-command-line "rake rcov RCOVOPTS='--gcc --no-html'"
"Rcov command line to find uncovered code.
It is good to use rcov with Rake because it `cd's appropriate directory.
`--gcc' option is strongly recommended because `rcov' uses compilation-mode.")
(defvar rcovsave-command-line "rake rcov RCOVOPTS='--gcc --no-html'"
"Rcov command line to save coverage status. See also `rcov-command-line'.")
(defvar rcovdiff-command-line "rake rcov RCOVOPTS='-D --gcc --no-html'"
"Rcov command line to find new uncovered code. See also `rcov-command-line'.")
;;;; rcov-xref-mode
(define-derived-mode rcov-xref-mode ruby-mode "Rxref"
"Major mode for annotated Ruby scripts (coverage/*.rb) by rcov."
(setq truncate-lines t)
;; ruby-electric-mode / pabbrev-mode hijacks TAB binding.
(and ruby-electric-mode (ruby-electric-mode -1))
(and (boundp 'pabbrev-mode) pabbrev-mode (pabbrev-mode -1))
(suppress-keymap rcov-xref-mode-map)
(define-key rcov-xref-mode-map "\C-i" 'rcov-xref-next-tag)
(define-key rcov-xref-mode-map "\M-\C-i" 'rcov-xref-previous-tag)
(define-key rcov-xref-mode-map "\C-m" 'rcov-xref-visit-source)
(set (make-local-variable 'automatic-hscrolling) nil)
(defvar rcov-xref-tag-regexp "\\[\\[\\(.*?\\)\\]\\]")
(defun rcov-xref-next-tag (n)
"Go to next LINK."
(interactive "p")
(when (looking-at rcov-xref-tag-regexp)
(goto-char (match-end 0)))
(when (re-search-forward rcov-xref-tag-regexp nil t n)
(goto-char (match-beginning 0)))
(defun rcov-xref-previous-tag (n)
"Go to previous LINK."
(interactive "p")
(re-search-backward rcov-xref-tag-regexp nil t n)
(defvar rcov-xref-link-tempbuffer " *rcov-link*")
(defun rcov-xref-show-link ()
"Follow current LINK."
(let ((link (match-string 1))
(eol (point-at-eol)))
(when (and link
(re-search-backward "# \\(>>\\|<<\\) " (point-at-bol) t))
(while (re-search-forward rcov-xref-tag-regexp eol t)
(let ((matched (match-string 1)))
(when (string= link matched)
(add-text-properties 0 (length matched) '(face highlight) matched))
(with-current-buffer (get-buffer-create rcov-xref-link-tempbuffer)
(insert matched "\n"))))
(let (message-log-max) ; inhibit *Messages*
(message "%s" (with-current-buffer rcov-xref-link-tempbuffer
(substring (buffer-string) 0 -1)))) ; chomp
(kill-buffer rcov-xref-link-tempbuffer)))))
;; copied from jw-visit-source
(defun rcov-xref-extract-file-lines (line)
"Extract a list of file/line pairs from the given line of text."
((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))))
(defun rcov-xref-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 (rcov-xref-select-file-line (cdr candidates))) ))
(defun rcov-xref-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."
(let* ((line (progn (looking-at rcov-xref-tag-regexp) (match-string 1)))
(candidates (rcov-xref-extract-file-lines line))
(file-line (rcov-xref-select-file-line candidates)))
(cond (file-line
(run-hooks 'rcov-xref-before-visit-source-hook)
(find-file (car file-line))
(goto-line (cadr file-line))
(run-hooks 'rcov-xref-after-visit-source-hook))
(error "No source location on line.")) )))
;;;; Running rcov with various options.
(defun rcov-internal (cmdline)
"Run rcov with various options."
(compile-internal cmdline ""
nil nil nil (lambda (x) "*rcov*")))
(defun rcov ()
"Run rcov to find uncovered code."
(rcov-internal rcov-command-line))
(defun rcovsave ()
"Run rcov to save coverage status."
(rcov-internal rcovsave-command-line))
(defun rcovdiff ()
"Run rcov to find new uncovered code."
(rcov-internal rcovdiff-command-line))
(provide 'rcov)