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