]> code.delx.au - gnu-emacs/blobdiff - lisp/vc/add-log.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / vc / add-log.el
index eb7e5bfdfad674ef3ecf57457a13f2cf2ecf8f5c..9076d834c7c1f731dcbce4901463675e2c83fde8 100644 (file)
@@ -1,6 +1,6 @@
 ;;; add-log.el --- change log maintenance commands for Emacs
 
-;; Copyright (C) 1985-1986, 1988, 1993-1994, 1997-1998, 2000-2015 Free
+;; Copyright (C) 1985-1986, 1988, 1993-1994, 1997-1998, 2000-2016 Free
 ;; Software Foundation, Inc.
 
 ;; Maintainer: emacs-devel@gnu.org
@@ -158,7 +158,7 @@ use the file's name relative to the directory of the change log file."
   :group 'change-log)
 
 (defcustom change-log-version-number-regexp-list
-  (let ((re "\\([0-9]+\.[0-9.]+\\)"))
+  (let ((re "\\([0-9]+\\.[0-9.]+\\)"))
     (list
      ;;  (defconst ad-version "2.15"
      (concat "^(def[^ \t\n]+[ \t]+[^ \t\n][ \t]\"" re)
@@ -171,6 +171,14 @@ Note: The search is conducted only within 10%, at the beginning of the file."
   :type '(repeat regexp)
   :group 'change-log)
 
+(defcustom change-log-directory-files '(".bzr" ".git" ".hg" ".svn")
+  "List of files that cause `find-change-log' to stop in containing directory.
+This applies if no pre-existing ChangeLog is found.  If nil, then in such
+a case simply use the directory containing the changed file."
+  :version "25.2"
+  :type '(repeat file)
+  :group 'change-log)
+
 (defface change-log-date
   '((t (:inherit font-lock-string-face)))
   "Face used to highlight dates in date lines."
@@ -481,9 +489,10 @@ try to visit the file for the change under `point' instead."
                (apply 'change-log-goto-source-1
                       (append change-log-find-head change-log-find-tail))
              (error
-              (format "Cannot find more matches for tag `%s' in file `%s'"
-                      (car change-log-find-head)
-                      (nth 2 change-log-find-head)))))
+              (format-message
+               "Cannot find more matches for tag `%s' in file `%s'"
+               (car change-log-find-head)
+               (nth 2 change-log-find-head)))))
     (save-excursion
       (let* ((at (point))
             (tag-at (change-log-search-tag-name))
@@ -516,8 +525,8 @@ try to visit the file for the change under `point' instead."
              (setq change-log-find-tail
                    (apply 'change-log-goto-source-1 change-log-find-head))
            (error
-            (format "Cannot find matches for tag `%s' in file `%s'"
-                    tag file)))))))))
+            (format-message "Cannot find matches for tag `%s' in file `%s'"
+                            tag file)))))))))
 
 (defun change-log-next-error (&optional argp reset)
   "Move to the Nth (default 1) next match in a ChangeLog buffer.
@@ -574,34 +583,21 @@ Compatibility function for \\[next-error] invocations."
 ;; called add-log-time-zone-rule since it's only used from add-log-* code.
 (defvaralias 'change-log-time-zone-rule 'add-log-time-zone-rule)
 (defvar add-log-time-zone-rule nil
-  "Time zone used for calculating change log time stamps.
-It takes the same format as the TZ argument of `set-time-zone-rule'.
-If nil, use local time.
-If t, use universal time.")
+  "Time zone rule used for calculating change log time stamps.
+If nil, use local time.  If t, use Universal Time.
+If a string, interpret as the ZONE argument of `format-time-string'.")
 (put 'add-log-time-zone-rule 'safe-local-variable
      (lambda (x) (or (booleanp x) (stringp x))))
 
-(defun add-log-iso8601-time-zone (&optional time)
-  (let* ((utc-offset (or (car (current-time-zone time)) 0))
-        (sign (if (< utc-offset 0) ?- ?+))
-        (sec (abs utc-offset))
-        (ss (% sec 60))
-        (min (/ sec 60))
-        (mm (% min 60))
-        (hh (/ min 60)))
-    (format (cond ((not (zerop ss)) "%c%02d:%02d:%02d")
-                 ((not (zerop mm)) "%c%02d:%02d")
-                 (t "%c%02d"))
-           sign hh mm ss)))
+(defun add-log-iso8601-time-zone (&optional time zone)
+  (declare (obsolete nil "25.2"))
+  (format-time-string "%:::z" time zone))
 
 (defvar add-log-iso8601-with-time-zone nil)
 
-(defun add-log-iso8601-time-string ()
-  (let ((time (format-time-string "%Y-%m-%d"
-                                  nil (eq t add-log-time-zone-rule))))
-    (if add-log-iso8601-with-time-zone
-        (concat time " " (add-log-iso8601-time-zone))
-      time)))
+(defun add-log-iso8601-time-string (&optional time zone)
+  (format-time-string
+   (if add-log-iso8601-with-time-zone "%Y-%m-%d %:::z" "%Y-%m-%d") time zone))
 
 (defun change-log-name ()
   "Return (system-dependent) default name for a change log file."
@@ -686,12 +682,16 @@ nil, by matching `change-log-version-number-regexp-list'."
 
 Optional arg FILE-NAME specifies the file to use.
 If FILE-NAME is nil, use the value of `change-log-default-name'.
-If `change-log-default-name' is nil, behave as though it were 'ChangeLog'
+If `change-log-default-name' is nil, behave as though it were \"ChangeLog\"
 \(or whatever we use on this operating system).
 
 If `change-log-default-name' contains a leading directory component, then
 simply find it in the current directory.  Otherwise, search in the current
-directory and its successive parents for a file so named.
+directory and its successive parents for a file so named.  Stop at the first
+such file that exists (or has a buffer visiting it), or the first directory
+that contains any of `change-log-directory-files'.  If no match is found,
+use the current directory.  To override the choice of this function,
+simply create an empty ChangeLog file first by hand in the desired place.
 
 Once a file is found, `change-log-default-name' is set locally in the
 current buffer to the complete file name.
@@ -724,24 +724,27 @@ Optional arg BUFFER-FILE overrides `buffer-file-name'."
          ;; for several related directories.
          (setq file-name (file-chase-links file-name))
          (setq file-name (expand-file-name file-name))
-         ;; Move up in the dir hierarchy till we find a change log file.
-         (let ((file1 file-name)
-               parent-dir)
-           (while (and (not (or (get-file-buffer file1) (file-exists-p file1)))
-                       (progn (setq parent-dir
-                                    (file-name-directory
-                                     (directory-file-name
-                                      (file-name-directory file1))))
-                              ;; Give up if we are already at the root dir.
-                              (not (string= (file-name-directory file1)
-                                            parent-dir))))
-             ;; Move up to the parent dir and try again.
-             (setq file1 (expand-file-name
-                          (file-name-nondirectory (change-log-name))
-                          parent-dir)))
-           ;; If we found a change log in a parent, use that.
-           (if (or (get-file-buffer file1) (file-exists-p file1))
-               (setq file-name file1)))))
+         (let* ((cbase (file-name-nondirectory (change-log-name)))
+                (root
+                 (locate-dominating-file
+                  file-name
+                  (lambda (dir)
+                    (or
+                     (let ((clog (expand-file-name cbase dir)))
+                       (or (get-file-buffer clog) (file-exists-p clog)))
+                     ;; Stop at VCS root?
+                     (and change-log-directory-files
+                          (let ((files change-log-directory-files)
+                                found)
+                            (while
+                                (and
+                                 (not
+                                  (setq found
+                                        (file-exists-p
+                                         (expand-file-name (car files) dir))))
+                                 (setq files (cdr files))))
+                            found)))))))
+           (if root (setq file-name (expand-file-name cbase root))))))
     ;; Make a local variable in this buffer so we needn't search again.
     (set (make-local-variable 'change-log-default-name) file-name))
   file-name)
@@ -848,14 +851,8 @@ non-nil, otherwise in local time."
       (let ((new-entries
              (mapcar (lambda (addr)
                        (concat
-                        (if (stringp add-log-time-zone-rule)
-                            (let ((tz (getenv "TZ")))
-                              (unwind-protect
-                                  (progn
-                                    (setenv "TZ" add-log-time-zone-rule)
-                                    (funcall add-log-time-format))
-                                (setenv "TZ" tz)))
-                          (funcall add-log-time-format))
+                        (funcall add-log-time-format
+                                 nil add-log-time-zone-rule)
                         "  " full-name
                         "  <" addr ">"))
                      (if (consp mailing-address)
@@ -902,8 +899,10 @@ non-nil, otherwise in local time."
                              "\\(\\s \\|[(),:]\\)")
                      bound t)))
              ;; Add to the existing item for the same file.
-             (re-search-forward "^\\s *$\\|^\\s \\*")
-             (goto-char (match-beginning 0))
+             (if (re-search-forward "^\\s *$\\|^\\s \\*" nil t)
+                 (goto-char (match-beginning 0))
+               (goto-char (point-max))
+               (insert "\n"))
              ;; Delete excess empty lines; make just 2.
              (while (and (not (eobp)) (looking-at "^\\s *$"))
                (delete-region (point) (line-beginning-position 2)))