Also require comint when loading.
[bpt/emacs.git] / lisp / add-log.el
index 546f87b..c9fdb34 100644 (file)
@@ -1,7 +1,7 @@
 ;;; add-log.el --- change log maintenance commands for Emacs
 
 ;; Copyright (C) 1985, 1986, 1988, 1993, 1994, 1997, 1998, 2000, 2001,
-;;   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+;;   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: tools
@@ -240,8 +240,11 @@ Note: The search is conducted only within 10%, at the beginning of the file."
 ;; backward-compatibility alias
 (put 'change-log-acknowledgement-face 'face-alias 'change-log-acknowledgement)
 
+(defconst change-log-file-names-re "^\\( +\\|\t\\)\\* \\([^ ,:([\n]+\\)")
+(defconst change-log-start-entry-re "^\\sw.........[0-9:+ ]*")
+
 (defvar change-log-font-lock-keywords
-  '(;;
+  `(;;
     ;; Date lines, new (2000-01-01) and old (Sat Jan  1 00:00:00 2000) styles.
     ;; Fixme: this regepx is just an approximate one and may match
     ;; wrongly with a non-date line existing as a random note.  In
@@ -255,7 +258,7 @@ Note: The search is conducted only within 10%, at the beginning of the file."
       (2 'change-log-email)))
     ;;
     ;; File names.
-    ("^\\( +\\|\t\\)\\* \\([^ ,:([\n]+\\)"
+    (,change-log-file-names-re
      (2 'change-log-file)
      ;; Possibly further names in a list:
      ("\\=, \\([^ ,:([\n]+\\)" nil nil (1 'change-log-file))
@@ -287,10 +290,49 @@ Note: The search is conducted only within 10%, at the beginning of the file."
      3 'change-log-acknowledgement))
   "Additional expressions to highlight in Change Log mode.")
 
+(defun change-log-search-file-name (where)
+  "Return the file-name for the change under point."
+  (save-excursion
+    (goto-char where)
+    (beginning-of-line 1)
+    (if (looking-at change-log-start-entry-re)
+       ;; We are at the start of an entry, search forward for a file
+       ;; name.
+       (progn
+         (re-search-forward change-log-file-names-re nil t)
+         (match-string 2))
+      (if (looking-at change-log-file-names-re)
+         ;; We found a file name.
+         (match-string 2)
+       ;; Look backwards for either a file name or the log entry start.
+       (if (re-search-backward
+            (concat "\\(" change-log-start-entry-re 
+                    "\\)\\|\\("
+                    change-log-file-names-re "\\)") nil t)
+           (if (match-beginning 1)
+               ;; We got the start of the entry, look forward for a
+               ;; file name.
+               (progn
+                 (re-search-forward change-log-file-names-re nil t)
+                 (match-string 2))
+             (match-string 4))
+         ;; We must be before any file name, look forward.
+         (re-search-forward change-log-file-names-re nil t)
+         (match-string 2))))))
+
+(defun change-log-find-file ()
+  "Visit the file for the change under point."
+  (interactive)
+  (let ((file (change-log-search-file-name (point))))
+    (if (and file (file-exists-p file))
+       (find-file file)
+      (message "No such file or directory: %s" file))))
+
 (defvar change-log-mode-map
   (let ((map (make-sparse-keymap)))
     (define-key map [?\C-c ?\C-p] 'add-log-edit-prev-comment)
     (define-key map [?\C-c ?\C-n] 'add-log-edit-next-comment)
+    (define-key map [?\C-c ?\C-f] 'change-log-find-file)
     map)
   "Keymap for Change Log major mode.")
 
@@ -379,7 +421,7 @@ With a numeric prefix ARG, go back ARG comments."
 
 (defun change-log-version-number-search ()
   "Return version number of current buffer's file.
-This is the value returned by `vc-workfile-version' or, if that is
+This is the value returned by `vc-working-revision' or, if that is
 nil, by matching `change-log-version-number-regexp-list'."
   (let* ((size (buffer-size))
         (limit
@@ -390,7 +432,7 @@ nil, by matching `change-log-version-number-regexp-list'."
          ;; Apply percentage only if buffer size is bigger than
          ;; approx 100 lines.
          (if (> size (* 100 80)) (+ (point) (/ size 10)))))
-    (or (and buffer-file-name (vc-workfile-version buffer-file-name))
+    (or (and buffer-file-name (vc-working-revision buffer-file-name))
        (save-restriction
          (widen)
          (let ((regexps change-log-version-number-regexp-list)
@@ -664,7 +706,6 @@ the change log file in another window."
                   (list current-prefix-arg
                         (prompt-for-change-log-name))))
   (add-change-log-entry whoami file-name t))
-;;;###autoload (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window)
 
 
 (defvar change-log-indent-text 0)
@@ -760,7 +801,33 @@ Runs `change-log-mode-hook'.
        'change-log-resolve-conflict)
   (set (make-local-variable 'adaptive-fill-regexp) "\\s *")
   (set (make-local-variable 'font-lock-defaults)
-       '(change-log-font-lock-keywords t nil nil backward-paragraph)))
+       '(change-log-font-lock-keywords t nil nil backward-paragraph))
+  (set (make-local-variable 'isearch-buffers-next-buffer-function)
+       'change-log-next-buffer)
+  (set (make-local-variable 'beginning-of-defun-function) 
+       'change-log-beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function) 
+       'change-log-end-of-defun)
+  (isearch-buffers-minor-mode))
+
+(defun change-log-next-buffer (&optional buffer wrap)
+  "Return the next buffer in the series of ChangeLog file buffers.
+This function is used for multiple buffers isearch.
+A sequence of buffers is formed by ChangeLog files with decreasing
+numeric file name suffixes in the directory of the initial ChangeLog
+file were isearch was started."
+  (let* ((name (change-log-name))
+        (files (cons name (sort (file-expand-wildcards
+                                 (concat name "[-.][0-9]*"))
+                                (lambda (a b)
+                                  (version< (substring b (length name))
+                                            (substring a (length name)))))))
+        (files (if isearch-forward files (reverse files))))
+    (find-file-noselect
+     (if wrap
+        (car files)
+       (cadr (member (file-name-nondirectory (buffer-file-name buffer))
+                    files))))))
 
 ;; It might be nice to have a general feature to replace this.  The idea I
 ;; have is a variable giving a regexp matching text which should not be
@@ -801,6 +868,9 @@ Prefix arg means justify as well."
   '(TeX-mode plain-TeX-mode LaTeX-mode tex-mode)
   "*Modes that look like TeX to `add-log-current-defun'.")
 
+(declare-function c-beginning-of-defun "cc-cmds" (&optional arg))
+(declare-function c-end-of-defun "cc-cmds" (&optional arg))
+
 ;;;###autoload
 (defun add-log-current-defun ()
   "Return name of function definition point is in, or nil.
@@ -1077,7 +1147,7 @@ Has a preference of looking backwards."
   "Return date of log entry in a consistent form for sorting.
 Point is assumed to be at the start of the entry."
   (require 'timezone)
-  (if (looking-at "^\\sw.........[0-9:+ ]*")
+  (if (looking-at change-log-start-entry-re)
       (let ((date (match-string-no-properties 0)))
        (if date
            (if (string-match "\\(....\\)-\\(..\\)-\\(..\\)\\s-+" date)
@@ -1164,6 +1234,32 @@ old-style time formats for entries are supported."
              (goto-char (point-max)))
            (insert-buffer-substring other-buf start)))))))
 
+(defun change-log-beginning-of-defun ()
+  (re-search-backward change-log-start-entry-re nil 'move))
+
+(defun change-log-end-of-defun ()
+  ;; Look back and if there is no entry there it means we are before
+  ;; the first ChangeLog entry, so go forward until finding one.
+  (unless (save-excursion (re-search-backward change-log-start-entry-re nil t))
+    (re-search-forward change-log-start-entry-re nil t))
+
+  ;; In case we are at the end of log entry going forward a line will
+  ;; make us find the next entry when searching. If we are inside of
+  ;; an entry going forward a line will still keep the point inside
+  ;; the same entry.
+  (forward-line 1)
+
+  ;; In case we are at the beginning of an entry, move past it.
+  (when (looking-at change-log-start-entry-re)
+    (goto-char (match-end 0))
+    (forward-line 1))
+
+  ;; Search for the start of the next log entry.  Go to the end of the
+  ;; buffer if we could not find a next entry.
+  (when (re-search-forward change-log-start-entry-re nil 'move)
+    (goto-char (match-beginning 0))
+    (forward-line -1)))
+
 (provide 'add-log)
 
 ;; arch-tag: 81eee6fc-088f-4372-a37f-80ad9620e762