forked from relevance/rcov
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrcov.el
131 lines (115 loc) · 4.94 KB
/
rcov.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
;;; rcov.el -- Ruby Coverage Analysis Tool
;;; Copyright (c) 2006 rubikitch <[email protected]>
;;;
;;; 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 --save=coverage.info'"
"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)))
(rcov-xref-show-link))
(defun rcov-xref-previous-tag (n)
"Go to previous LINK."
(interactive "p")
(re-search-backward rcov-xref-tag-regexp nil t n)
(rcov-xref-show-link))
(defvar rcov-xref-link-tempbuffer " *rcov-link*")
(defun rcov-xref-show-link ()
"Follow current LINK."
(let ((link (match-string 1))
(eol (point-at-eol)))
(save-excursion
(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."
(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 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."
(interactive)
(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))
(t
(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."
(interactive)
(rcov-internal rcov-command-line))
(defun rcovsave ()
"Run rcov to save coverage status."
(interactive)
(rcov-internal rcovsave-command-line))
(defun rcovdiff ()
"Run rcov to find new uncovered code."
(interactive)
(rcov-internal rcovdiff-command-line))
(provide 'rcov)