Add arch taglines
[bpt/emacs.git] / lisp / log-view.el
CommitLineData
e57a1038 1;;; log-view.el --- Major mode for browsing RCS/CVS/SCCS log output
5b467bf4 2
edb33387 3;; Copyright (C) 1999, 2000, 2001 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
66(defface log-view-file-face
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)
72(defvar log-view-file-face 'log-view-file-face)
73
74(defface log-view-message-face
75 '((((class color) (background light))
76 (:background "grey85"))
1fd714a4 77 (t (:weight bold)))
5b467bf4
SM
78 "Face for the message header line in `log-view-mode'."
79 :group 'log-view)
80(defvar log-view-message-face 'log-view-message-face)
81
82(defconst log-view-file-re
83 (concat "^\\("
84 "Working file: \\(.+\\)"
85 "\\|SCCS/s\\.\\(.+\\):"
86 "\\)\n"))
2a673b03
SM
87;; In RCS, a locked revision will look like "revision N.M\tlocked by: FOO".
88(defconst log-view-message-re "^\\(revision \\([.0-9]+\\)\\(?:\t.*\\)?\\|rev \\([0-9]+\\): .*\\|D \\([.0-9]+\\) .*\\)$")
5b467bf4
SM
89
90(defconst log-view-font-lock-keywords
91 `((,log-view-file-re
e57a1038
SM
92 (2 (if (boundp 'cvs-filename-face) cvs-filename-face) nil t)
93 (3 (if (boundp 'cvs-filename-face) cvs-filename-face) nil t)
94 (0 log-view-file-face append))
5b467bf4
SM
95 (,log-view-message-re . log-view-message-face)))
96(defconst log-view-font-lock-defaults
97 '(log-view-font-lock-keywords t nil nil nil))
98
edb33387 99;;;;
5b467bf4 100;;;; Actual code
edb33387 101;;;;
5b467bf4
SM
102
103;;;###autoload
cdbb990f 104(define-derived-mode log-view-mode fundamental-mode "Log-View"
5b467bf4 105 "Major mode for browsing CVS log output."
99cb8c8b 106 (setq buffer-read-only t)
5b467bf4
SM
107 (set (make-local-variable 'font-lock-defaults) log-view-font-lock-defaults)
108 (set (make-local-variable 'cvs-minor-wrap-function) 'log-view-minor-wrap))
109
110;;;;
111;;;; Navigation
112;;;;
113
cdbb990f
SM
114;; define log-view-{msg,file}-{next,prev}
115(easy-mmode-define-navigation log-view-msg log-view-message-re "log message")
116(easy-mmode-define-navigation log-view-file log-view-file-re "file")
5b467bf4 117
3e87f5fc
SM
118(defun log-view-goto-rev (rev)
119 (goto-char (point-min))
120 (ignore-errors
121 (while (not (equal rev (log-view-current-tag)))
122 (log-view-msg-next))
123 t))
124
5b467bf4
SM
125;;;;
126;;;; Linkage to PCL-CVS (mostly copied from cvs-status.el)
127;;;;
128
129(defconst log-view-dir-re "^cvs[.ex]* [a-z]+: Logging \\(.+\\)$")
130
131(defun log-view-current-file ()
132 (save-excursion
133 (forward-line 1)
134 (or (re-search-backward log-view-file-re nil t)
135 (re-search-forward log-view-file-re))
136 (let* ((file (or (match-string 2) (match-string 3)))
137 (cvsdir (and (re-search-backward log-view-dir-re nil t)
138 (match-string 1)))
e57a1038
SM
139 (pcldir (and (boundp 'cvs-pcl-cvs-dirchange-re)
140 (re-search-backward cvs-pcl-cvs-dirchange-re nil t)
5b467bf4
SM
141 (match-string 1)))
142 (dir ""))
143 (let ((default-directory ""))
144 (when pcldir (setq dir (expand-file-name pcldir dir)))
99cb8c8b
SS
145 (when cvsdir (setq dir (expand-file-name cvsdir dir))))
146 (expand-file-name file dir))))
5b467bf4 147
99cb8c8b 148(defun log-view-current-tag (&optional where)
cdbb990f 149 (save-excursion
99cb8c8b 150 (when where (goto-char where))
cdbb990f
SM
151 (forward-line 1)
152 (let ((pt (point)))
153 (when (re-search-backward log-view-message-re nil t)
467ee23f 154 (let ((rev (or (match-string 2) (match-string 3) (match-string 4))))
cdbb990f
SM
155 (unless (re-search-forward log-view-file-re pt t)
156 rev))))))
5b467bf4
SM
157
158(defun log-view-minor-wrap (buf f)
159 (let ((data (with-current-buffer buf
160 (cons
161 (cons (log-view-current-file)
162 (log-view-current-tag))
3e87f5fc 163 (when mark-active
5b467bf4
SM
164 (save-excursion
165 (goto-char (mark))
166 (cons (log-view-current-file)
167 (log-view-current-tag))))))))
168 (let ((cvs-branch-prefix (cdar data))
169 (cvs-secondary-branch-prefix (and (cdar data) (cddr data)))
170 (cvs-minor-current-files
171 (cons (caar data)
172 (when (and (cadr data) (not (equal (caar data) (cadr data))))
173 (list (cadr data)))))
174 ;; FIXME: I need to force because the fileinfos are UNKNOWN
175 (cvs-force-command "/F"))
176 (funcall f))))
177
c0313667
AS
178(defun log-view-find-version (pos)
179 "Visit the version at point."
180 (interactive "d")
181 (save-excursion
182 (goto-char pos)
f1180544 183 (switch-to-buffer (vc-find-version (log-view-current-file)
c0313667
AS
184 (log-view-current-tag)))))
185
467ee23f
SM
186;;
187;; diff
188;;
99cb8c8b
SS
189
190(defun log-view-diff (beg end)
191 "Get the diff for several revisions.
192If the point is the same as the mark, get the diff for this revision.
193Otherwise, get the diff between the revisions
194 were the region starts and ends."
195 (interactive "r")
196 (let ((fr (log-view-current-tag beg))
197 (to (log-view-current-tag end)))
198 (when (string-equal fr to)
199 (save-excursion
200 (goto-char end)
201 (log-view-msg-next)
202 (setq to (log-view-current-tag))))
203 (vc-version-diff (log-view-current-file) to fr)))
204
5b467bf4 205(provide 'log-view)
cdbb990f 206
ab5796a9 207;;; arch-tag: 0d64220b-ce7e-4f62-9c2a-6b04c2f81f4f
5b467bf4 208;;; log-view.el ends here