;;; 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, 2008, 2009, 2010
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1988, 1993-1994, 1997-1998, 2000-2013 Free
+;; Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: vc tools
;;; Code:
-(eval-when-compile
- (require 'timezone))
-
(defgroup change-log nil
"Change log maintenance."
:group 'tools
;;;###autoload
(defcustom add-log-current-defun-function nil
"If non-nil, function to guess name of surrounding function.
-It is used by `add-log-current-defun' in preference to built-in rules.
-Returns function's name as a string, or nil if outside a function."
+It is called by `add-log-current-defun' with no argument, and
+should return the function's name as a string, or nil if point is
+outside a function."
:type '(choice (const nil) function)
:group 'change-log)
:type 'boolean
:group 'change-log)
-(defcustom add-log-buffer-file-name-function nil
+(defvar add-log-buffer-file-name-function 'buffer-file-name
"If non-nil, function to call to identify the full filename of a buffer.
-This function is called with no argument. If this is nil, the default is to
-use `buffer-file-name'."
- :type '(choice (const nil) function)
- :group 'change-log)
+This function is called with no argument. The default is to
+use `buffer-file-name'.")
(defcustom add-log-file-name-function nil
"If non-nil, function to call to identify the filename for a ChangeLog entry.
(define-obsolete-face-alias 'change-log-function-face
'change-log-function "22.1")
-(defface change-log-acknowledgement
+(defface change-log-acknowledgment
'((t (:inherit font-lock-comment-face)))
"Face for highlighting acknowledgments."
:version "21.1"
:group 'change-log)
+(define-obsolete-face-alias 'change-log-acknowledgement
+ 'change-log-acknowledgment "24.3")
(define-obsolete-face-alias 'change-log-acknowledgement-face
- 'change-log-acknowledgement "22.1")
+ 'change-log-acknowledgment "22.1")
(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
+ ;; Fixme: this regexp is just an approximate one and may match
;; wrongly with a non-date line existing as a random note. In
;; addition, using any kind of fixed setting like this doesn't
;; work if a user customizes add-log-time-format.
- ("^[0-9-]+ +\\|^ \\{11,\\}\\|^\\(Sun\\|Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\) [A-z][a-z][a-z] [0-9:+ ]+"
+ ("^[0-9-]+ +\\|^ \\{11,\\}\\|^\t \\{3,\\}\\|^\\(Sun\\|Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\) [A-z][a-z][a-z] [0-9:+ ]+"
(0 'change-log-date-face)
;; Name and e-mail; some people put e-mail in parens, not angles.
("\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" nil nil
;; Function of change.
("<\\([^>\n]+\\)>\\(:\\| (\\)" (1 'change-log-function))
;;
- ;; Acknowledgements.
+ ;; Acknowledgments.
;; Don't include plain "From" because that is vague;
;; we want to encourage people to say something more specific.
;; Note that the FSF does not use "Patches by"; our convention
;; is to put the name of the author of the changes at the top
;; of the change log entry.
- ("\\(^\\( +\\|\t\\)\\| \\)\\(Patch\\(es\\)? by\\|Report\\(ed by\\| from\\)\\|Suggest\\(ed by\\|ion from\\)\\)"
- 3 'change-log-acknowledgement))
+ ("\\(^\\( +\\|\t\\)\\| \\)\\(Thanks to\\|Patch\\(es\\)? by\\|Report\\(ed by\\| from\\)\\|Suggest\\(ed by\\|ion from\\)\\)"
+ 3 'change-log-acknowledgment))
"Additional expressions to highlight in Change Log mode.")
(defun change-log-search-file-name (where)
If nil, use local time.
If t, use universal time.")
(put 'add-log-time-zone-rule 'safe-local-variable
- '(lambda (x) (or (booleanp x) (stringp x))))
+ (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))
Optional arg BUFFER-FILE overrides `buffer-file-name'."
;; If we are called from a diff, first switch to the source buffer;
;; in order to respect buffer-local settings of change-log-default-name, etc.
- (with-current-buffer (let ((buff (if (eq major-mode 'diff-mode)
+ (with-current-buffer (let ((buff (if (derived-mode-p 'diff-mode)
(car (ignore-errors
(diff-find-source-location))))))
(if (buffer-live-p buff) buff
(let* ((defun (add-log-current-defun))
(version (and change-log-version-info-enabled
(change-log-version-number-search)))
- (buf-file-name (if add-log-buffer-file-name-function
- (funcall add-log-buffer-file-name-function)
- buffer-file-name))
+ (buf-file-name (funcall add-log-buffer-file-name-function))
(buffer-file (if buf-file-name (expand-file-name buf-file-name)))
(file-name (expand-file-name (find-change-log file-name buffer-file)))
;; Set ITEM to the file name to use in the new item.
(let ((tz (getenv "TZ")))
(unwind-protect
(progn
- (set-time-zone-rule add-log-time-zone-rule)
+ (setenv "TZ" add-log-time-zone-rule)
(funcall add-log-time-format))
- (set-time-zone-rule tz)))
+ (setenv "TZ" tz)))
(funcall add-log-time-format))
" " full-name
" <" addr ">"))
(if (and (not add-log-always-start-new-record)
(let ((hit nil))
(dolist (entry new-entries hit)
- (when (looking-at (regexp-quote entry))
- (setq hit t)))))
+ (and (looking-at (regexp-quote entry))
+ ;; Reject multiple author entries. (Bug#8645)
+ (save-excursion
+ (forward-line 1)
+ (not (looking-at "[ \t]+.*<.*>$")))
+ (setq hit t)))))
(forward-line 1)
(insert (nth (random (length new-entries))
new-entries)
(point))))
;; Now insert the new line for this item.
- (cond ((re-search-forward "^\\s *\\*\\s *$" bound t)
+ (cond ((re-search-forward "^\\s *\\* *$" bound t)
;; Put this file name into the existing empty item.
(if item
(insert item)))
;; No function name, so put in a colon unless we have just a star.
(unless (save-excursion
(beginning-of-line 1)
- (looking-at "\\s *\\(\\*\\s *\\)?$"))
+ (looking-at "\\s *\\(\\* *\\)?$"))
(insert ": ")
(if version (insert version ?\s)))
;; Make it easy to get rid of the function name.
show-trailing-whitespace t)
(set (make-local-variable 'fill-forward-paragraph-function)
'change-log-fill-forward-paragraph)
+ (set (make-local-variable 'comment-start) nil)
;; Make sure we call `change-log-indent' when filling.
(set (make-local-variable 'fill-indent-according-to-mode) t)
;; Avoid that filling leaves behind a single "*" on a line.
(add-hook 'fill-nobreak-predicate
- '(lambda ()
- (looking-back "^\\s *\\*\\s *" (line-beginning-position)))
+ (lambda ()
+ (looking-back "^\\s *\\*\\s *" (line-beginning-position)))
nil t)
(set (make-local-variable 'indent-line-function) 'change-log-indent)
(set (make-local-variable 'tab-always-indent) nil)
:type 'regexp
:group 'change-log)
-;;;###autoload
-(defvar add-log-lisp-like-modes
- '(emacs-lisp-mode lisp-mode scheme-mode dsssl-mode lisp-interaction-mode)
- "*Modes that look like Lisp to `add-log-current-defun'.")
-
-;;;###autoload
-(defvar add-log-c-like-modes
- '(c-mode c++-mode c++-c-mode objc-mode)
- "*Modes that look like C to `add-log-current-defun'.")
-
-;;;###autoload
-(defvar add-log-tex-like-modes
- '(TeX-mode plain-TeX-mode LaTeX-mode tex-mode)
- "*Modes that look like TeX to `add-log-current-defun'.")
-
(declare-function c-cpp-define-name "cc-cmds" ())
(declare-function c-defun-name "cc-cmds" ())
Has a preference of looking backwards."
(condition-case nil
(save-excursion
- (let ((location (point)))
- (cond (add-log-current-defun-function
- (funcall add-log-current-defun-function))
- ((apply 'derived-mode-p add-log-lisp-like-modes)
- ;; If we are now precisely at the beginning of a defun,
- ;; make sure beginning-of-defun finds that one
- ;; rather than the previous one.
- (or (eobp) (forward-char 1))
- (beginning-of-defun)
- ;; Make sure we are really inside the defun found,
- ;; not after it.
- (when (and (looking-at "\\s(")
- (progn (end-of-defun)
- (< location (point)))
- (progn (forward-sexp -1)
- (>= location (point))))
- (if (looking-at "\\s(")
- (forward-char 1))
- ;; Skip the defining construct name, typically "defun"
- ;; or "defvar".
- (forward-sexp 1)
- ;; The second element is usually a symbol being defined.
- ;; If it is not, use the first symbol in it.
- (skip-chars-forward " \t\n'(")
- (buffer-substring-no-properties (point)
- (progn (forward-sexp 1)
- (point)))))
- ((apply 'derived-mode-p add-log-c-like-modes)
- (or (c-cpp-define-name)
- (c-defun-name)))
- ((memq major-mode add-log-tex-like-modes)
- (if (re-search-backward
- "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)"
- nil t)
- (progn
- (goto-char (match-beginning 0))
- (buffer-substring-no-properties
- (1+ (point)) ; without initial backslash
- (line-end-position)))))
- ((derived-mode-p 'texinfo-mode)
- (if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t)
- (match-string-no-properties 1)))
- ((derived-mode-p 'perl-mode 'cperl-mode)
- (if (re-search-backward "^sub[ \t]+\\([^({ \t\n]+\\)" nil t)
- (match-string-no-properties 1)))
- ;; Emacs's autoconf-mode installs its own
- ;; `add-log-current-defun-function'. This applies to
- ;; a different mode apparently for editing .m4
- ;; autoconf source.
- ((derived-mode-p 'autoconf-mode)
- (if (re-search-backward
- "^\\(\\(m4_\\)?define\\|A._DEFUN\\)(\\[?\\([A-Za-z0-9_]+\\)" nil t)
- (match-string-no-properties 3)))
- (t
- ;; If all else fails, try heuristics
- (let (case-fold-search
- result)
- (end-of-line)
- (when (re-search-backward
- add-log-current-defun-header-regexp
- (- (point) 10000)
- t)
- (setq result (or (match-string-no-properties 1)
- (match-string-no-properties 0)))
- ;; Strip whitespace away
- (when (string-match "\\([^ \t\n\r\f].*[^ \t\n\r\f]\\)"
- result)
- (setq result (match-string-no-properties 1 result)))
- result))))))
+ (if add-log-current-defun-function
+ (funcall add-log-current-defun-function)
+ ;; If all else fails, try heuristics
+ (let (case-fold-search
+ result)
+ (end-of-line)
+ (when (re-search-backward add-log-current-defun-header-regexp
+ (- (point) 10000) t)
+ (setq result (or (match-string-no-properties 1)
+ (match-string-no-properties 0)))
+ ;; Strip whitespace away
+ (when (string-match "\\([^ \t\n\r\f].*[^ \t\n\r\f]\\)"
+ result)
+ (setq result (match-string-no-properties 1 result)))
+ result))))
(error nil)))
(defvar change-log-get-method-definition-md)
(change-log-get-method-definition-1 ""))
(concat change-log-get-method-definition-md "]"))))))
\f
+(autoload 'timezone-make-date-sortable "timezone")
+
(defun change-log-sortable-date-at ()
"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 change-log-start-entry-re)
(let ((date (match-string-no-properties 0)))
(if date
(if (string-match "\\(....\\)-\\(..\\)-\\(..\\)\\s-+" date)
(concat (match-string 1 date) (match-string 2 date)
(match-string 3 date))
- (condition-case nil
- (timezone-make-date-sortable date)
- (error nil)))))
+ (ignore-errors (timezone-make-date-sortable date)))))
(error "Bad date")))
(defun change-log-resolve-conflict ()
(provide 'add-log)
-;; arch-tag: 81eee6fc-088f-4372-a37f-80ad9620e762
;;; add-log.el ends here