(menu-bar-options-menu): Delete "Syntax
[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)
198 "Get the diff for several revisions.
199If the point is the same as the mark, get the diff for this revision.
200Otherwise, get the diff between the revisions
da4ae7d3
JL
201were the region starts and ends."
202 (interactive
203 (list (if mark-active (region-beginning) (point))
204 (if mark-active (region-end) (point))))
99cb8c8b
SS
205 (let ((fr (log-view-current-tag beg))
206 (to (log-view-current-tag end)))
207 (when (string-equal fr to)
208 (save-excursion
209 (goto-char end)
210 (log-view-msg-next)
211 (setq to (log-view-current-tag))))
212 (vc-version-diff (log-view-current-file) to fr)))
213
5b467bf4 214(provide 'log-view)
cdbb990f 215
9be92b96 216;; arch-tag: 0d64220b-ce7e-4f62-9c2a-6b04c2f81f4f
5b467bf4 217;;; log-view.el ends here