(cl-macroexpand-all): Fix code-walk for
[bpt/emacs.git] / lisp / log-view.el
CommitLineData
e57a1038 1;;; log-view.el --- Major mode for browsing RCS/CVS/SCCS log output
5b467bf4 2
0d30b337
TTN
3;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
4;; 2005 Free Software Foundation, Inc.
5b467bf4
SM
5
6;; Author: Stefan Monnier <monnier@cs.yale.edu>
e57a1038 7;; Keywords: rcs sccs cvs log version-control
5b467bf4
SM
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs; see the file COPYING. If not, write to the
086add15
LK
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
5b467bf4
SM
25
26;;; Commentary:
27
28;; Todo:
29
5b467bf4
SM
30;; - add compatibility with cvs-log.el
31;; - add ability to modify a log-entry (via cvs-mode-admin ;-)
e57a1038 32;; - remove references to cvs-*
5b467bf4
SM
33
34;;; Code:
35
36(eval-when-compile (require 'cl))
5b467bf4 37(require 'pcvs-util)
99cb8c8b 38(autoload 'vc-version-diff "vc")
5b467bf4 39
71f6f911
JB
40(defvar cvs-minor-wrap-function)
41
5b467bf4 42(defgroup log-view nil
e57a1038 43 "Major mode for browsing log output of RCS/CVS/SCCS."
5b467bf4
SM
44 :group 'pcl-cvs
45 :prefix "log-view-")
46
47(easy-mmode-defmap log-view-mode-map
99cb8c8b
SS
48 '(("q" . quit-window)
49 ("z" . kill-this-buffer)
50 ("m" . set-mark-command)
2a673b03 51 ;; ("e" . cvs-mode-edit-log)
99cb8c8b 52 ("d" . log-view-diff)
c0313667 53 ("f" . log-view-find-version)
99cb8c8b 54 ("n" . log-view-msg-next)
cdbb990f
SM
55 ("p" . log-view-msg-prev)
56 ("N" . log-view-file-next)
57 ("P" . log-view-file-prev)
e2c2a3e2
KG
58 ("\M-n" . log-view-file-next)
59 ("\M-p" . log-view-file-prev))
5b467bf4
SM
60 "Log-View's keymap."
61 :group 'log-view
e57a1038
SM
62 ;; Here I really need either buffer-local keymap-inheritance
63 ;; or a minor-mode-map with lower precedence than the local map.
64 :inherit (if (boundp 'cvs-mode-map) cvs-mode-map))
5b467bf4
SM
65
66(defvar log-view-mode-hook nil
67 "Hook run at the end of `log-view-mode'.")
68
d842de85 69(defface log-view-file
5b467bf4 70 '((((class color) (background light))
1fd714a4
RS
71 (:background "grey70" :weight bold))
72 (t (:weight bold)))
5b467bf4
SM
73 "Face for the file header line in `log-view-mode'."
74 :group 'log-view)
d842de85
MB
75;; backward-compatibility alias
76(put 'log-view-file-face 'face-alias 'log-view-file)
77(defvar log-view-file-face 'log-view-file)
5b467bf4 78
d842de85 79(defface log-view-message
5b467bf4
SM
80 '((((class color) (background light))
81 (:background "grey85"))
1fd714a4 82 (t (:weight bold)))
5b467bf4
SM
83 "Face for the message header line in `log-view-mode'."
84 :group 'log-view)
d842de85
MB
85;; backward-compatibility alias
86(put 'log-view-message-face 'face-alias 'log-view-message)
87(defvar log-view-message-face 'log-view-message)
5b467bf4
SM
88
89(defconst log-view-file-re
90 (concat "^\\("
91 "Working file: \\(.+\\)"
92 "\\|SCCS/s\\.\\(.+\\):"
93 "\\)\n"))
2a673b03 94;; In RCS, a locked revision will look like "revision N.M\tlocked by: FOO".
9be92b96 95(defconst log-view-message-re "^\\(revision \\([.0-9]+\\)\\(?:\t.*\\)?\\|r\\([0-9]+\\) | .* | .*\\|D \\([.0-9]+\\) .*\\)$")
5b467bf4
SM
96
97(defconst log-view-font-lock-keywords
98 `((,log-view-file-re
e57a1038
SM
99 (2 (if (boundp 'cvs-filename-face) cvs-filename-face) nil t)
100 (3 (if (boundp 'cvs-filename-face) cvs-filename-face) nil t)
101 (0 log-view-file-face append))
5b467bf4
SM
102 (,log-view-message-re . log-view-message-face)))
103(defconst log-view-font-lock-defaults
104 '(log-view-font-lock-keywords t nil nil nil))
105
edb33387 106;;;;
5b467bf4 107;;;; Actual code
edb33387 108;;;;
5b467bf4
SM
109
110;;;###autoload
cdbb990f 111(define-derived-mode log-view-mode fundamental-mode "Log-View"
5b467bf4 112 "Major mode for browsing CVS log output."
99cb8c8b 113 (setq buffer-read-only t)
5b467bf4
SM
114 (set (make-local-variable 'font-lock-defaults) log-view-font-lock-defaults)
115 (set (make-local-variable 'cvs-minor-wrap-function) 'log-view-minor-wrap))
116
117;;;;
118;;;; Navigation
119;;;;
120
cdbb990f
SM
121;; define log-view-{msg,file}-{next,prev}
122(easy-mmode-define-navigation log-view-msg log-view-message-re "log message")
123(easy-mmode-define-navigation log-view-file log-view-file-re "file")
5b467bf4 124
3e87f5fc
SM
125(defun log-view-goto-rev (rev)
126 (goto-char (point-min))
127 (ignore-errors
128 (while (not (equal rev (log-view-current-tag)))
129 (log-view-msg-next))
130 t))
131
5b467bf4
SM
132;;;;
133;;;; Linkage to PCL-CVS (mostly copied from cvs-status.el)
134;;;;
135
136(defconst log-view-dir-re "^cvs[.ex]* [a-z]+: Logging \\(.+\\)$")
137
138(defun log-view-current-file ()
139 (save-excursion
140 (forward-line 1)
141 (or (re-search-backward log-view-file-re nil t)
142 (re-search-forward log-view-file-re))
143 (let* ((file (or (match-string 2) (match-string 3)))
144 (cvsdir (and (re-search-backward log-view-dir-re nil t)
145 (match-string 1)))
e57a1038
SM
146 (pcldir (and (boundp 'cvs-pcl-cvs-dirchange-re)
147 (re-search-backward cvs-pcl-cvs-dirchange-re nil t)
5b467bf4
SM
148 (match-string 1)))
149 (dir ""))
150 (let ((default-directory ""))
151 (when pcldir (setq dir (expand-file-name pcldir dir)))
99cb8c8b
SS
152 (when cvsdir (setq dir (expand-file-name cvsdir dir))))
153 (expand-file-name file dir))))
5b467bf4 154
99cb8c8b 155(defun log-view-current-tag (&optional where)
cdbb990f 156 (save-excursion
99cb8c8b 157 (when where (goto-char where))
cdbb990f
SM
158 (forward-line 1)
159 (let ((pt (point)))
160 (when (re-search-backward log-view-message-re nil t)
467ee23f 161 (let ((rev (or (match-string 2) (match-string 3) (match-string 4))))
cdbb990f
SM
162 (unless (re-search-forward log-view-file-re pt t)
163 rev))))))
5b467bf4
SM
164
165(defun log-view-minor-wrap (buf f)
166 (let ((data (with-current-buffer buf
167 (cons
168 (cons (log-view-current-file)
169 (log-view-current-tag))
3e87f5fc 170 (when mark-active
5b467bf4
SM
171 (save-excursion
172 (goto-char (mark))
173 (cons (log-view-current-file)
174 (log-view-current-tag))))))))
175 (let ((cvs-branch-prefix (cdar data))
176 (cvs-secondary-branch-prefix (and (cdar data) (cddr data)))
177 (cvs-minor-current-files
178 (cons (caar data)
179 (when (and (cadr data) (not (equal (caar data) (cadr data))))
180 (list (cadr data)))))
181 ;; FIXME: I need to force because the fileinfos are UNKNOWN
182 (cvs-force-command "/F"))
183 (funcall f))))
184
c0313667
AS
185(defun log-view-find-version (pos)
186 "Visit the version at point."
187 (interactive "d")
188 (save-excursion
189 (goto-char pos)
f1180544 190 (switch-to-buffer (vc-find-version (log-view-current-file)
c0313667
AS
191 (log-view-current-tag)))))
192
467ee23f
SM
193;;
194;; diff
195;;
99cb8c8b
SS
196
197(defun log-view-diff (beg end)
e8171d36
JL
198 "Get the diff between two revisions.
199If the mark is not active or the mark is on the revision at point,
200get the diff between the revision at point and its previous revision.
201Otherwise, get the diff between the revisions where the region starts
202and ends."
da4ae7d3
JL
203 (interactive
204 (list (if mark-active (region-beginning) (point))
205 (if mark-active (region-end) (point))))
99cb8c8b
SS
206 (let ((fr (log-view-current-tag beg))
207 (to (log-view-current-tag end)))
208 (when (string-equal fr to)
209 (save-excursion
210 (goto-char end)
211 (log-view-msg-next)
212 (setq to (log-view-current-tag))))
213 (vc-version-diff (log-view-current-file) to fr)))
214
5b467bf4 215(provide 'log-view)
cdbb990f 216
9be92b96 217;; arch-tag: 0d64220b-ce7e-4f62-9c2a-6b04c2f81f4f
5b467bf4 218;;; log-view.el ends here