summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/copyright.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/copyright.el')
-rw-r--r--lisp/emacs-lisp/copyright.el113
1 files changed, 88 insertions, 25 deletions
diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el
index 96c846d912a..5ab50847f8c 100644
--- a/lisp/emacs-lisp/copyright.el
+++ b/lisp/emacs-lisp/copyright.el
@@ -43,17 +43,30 @@ A value of nil means to search whole buffer."
:type '(choice (integer :tag "Limit")
(const :tag "No limit")))
-;; The character classes have the Latin-1 version and the Latin-9
-;; version, which is probably enough.
+(defcustom copyright-at-end-flag nil
+ "Non-nil means to search backwards from the end of the buffer for copyright.
+This is useful for ChangeLogs."
+ :group 'copyright
+ :type 'boolean
+ :version "23.1")
+
(defcustom copyright-regexp
- "\\([]\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\
-\\|[Cc]opyright\\s *:?\\s *[]\\)\
+ "\\(©\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\
+\\|[Cc]opyright\\s *:?\\s *©\\)\
\\s *\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
"What your copyright notice looks like.
The second \\( \\) construct must match the years."
:group 'copyright
:type 'regexp)
+(defcustom copyright-names-regexp ""
+ "Regexp matching the names which correspond to the user.
+Only copyright lines where the name matches this regexp will be updated.
+This allows you to avoid adding years to a copyright notice belonging to
+someone else or to a group for which you do not work."
+ :group 'copyright
+ :type 'regexp)
+
(defcustom copyright-years-regexp
"\\(\\s *\\)\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
"Match additional copyright notice years.
@@ -82,10 +95,47 @@ When this is `function', only ask when called non-interactively."
(defvar copyright-current-year (substring (current-time-string) -4)
"String representing the current year.")
+(defsubst copyright-limit () ; re-search-forward BOUND
+ (and copyright-limit
+ (if copyright-at-end-flag
+ (- (point) copyright-limit)
+ (+ (point) copyright-limit))))
+
+(defun copyright-re-search (regexp &optional bound noerror count)
+ "Re-search forward or backward depending on `copyright-at-end-flag'."
+ (if copyright-at-end-flag
+ (re-search-backward regexp bound noerror count)
+ (re-search-forward regexp bound noerror count)))
+
+(defun copyright-start-point ()
+ "Return point-min or point-max, depending on `copyright-at-end-flag'."
+ (if copyright-at-end-flag
+ (point-max)
+ (point-min)))
+
+(defun copyright-offset-too-large-p ()
+ "Return non-nil if point is too far from the edge of the buffer."
+ (when copyright-limit
+ (if copyright-at-end-flag
+ (< (point) (- (point-max) copyright-limit))
+ (> (point) (+ (point-min) copyright-limit)))))
+
(defun copyright-update-year (replace noquery)
- (when (re-search-forward copyright-regexp
- (if copyright-limit (+ (point) copyright-limit)) t)
- ;; If the years are continued onto multiple lined
+ (when
+ (condition-case err
+ ;; (1) Need the extra \\( \\) around copyright-regexp because we
+ ;; goto (match-end 1) below. See note (2) below.
+ (copyright-re-search (concat "\\(" copyright-regexp
+ "\\)\\([ \t]*\n\\)?.*\\(?:"
+ copyright-names-regexp "\\)")
+ (copyright-limit)
+ t)
+ ;; In case the regexp is rejected. This is useful because
+ ;; copyright-update is typically called from before-save-hook where
+ ;; such an error is very inconvenient for the user.
+ (error (message "Can't update copyright: %s" err) nil))
+ (goto-char (match-end 1))
+ ;; If the years are continued onto multiple lines
;; that are marked as comments, skip to the end of the years anyway.
(while (save-excursion
(and (eq (following-char) ?,)
@@ -96,15 +146,16 @@ When this is `function', only ask when called non-interactively."
(forward-line 1)
(and (looking-at comment-start-skip)
(goto-char (match-end 0))))
- (save-match-data
- (looking-at copyright-years-regexp))))
+ (looking-at-p copyright-years-regexp)))
(forward-line 1)
(re-search-forward comment-start-skip)
- (re-search-forward copyright-years-regexp))
+ ;; (2) Need the extra \\( \\) so that the years are subexp 3, as
+ ;; they are at note (1) above.
+ (re-search-forward (format "\\(%s\\)" copyright-years-regexp)))
;; Note that `current-time-string' isn't locale-sensitive.
(setq copyright-current-year (substring (current-time-string) -4))
- (unless (string= (buffer-substring (- (match-end 2) 2) (match-end 2))
+ (unless (string= (buffer-substring (- (match-end 3) 2) (match-end 3))
(substring copyright-current-year -2))
(if (or noquery
(y-or-n-p (if replace
@@ -113,7 +164,7 @@ When this is `function', only ask when called non-interactively."
(concat "Add " copyright-current-year
" to copyright? "))))
(if replace
- (replace-match copyright-current-year t t nil 2)
+ (replace-match copyright-current-year t t nil 3)
(let ((size (save-excursion (skip-chars-backward "0-9"))))
(if (and (eq (% (- (string-to-number copyright-current-year)
(string-to-number (buffer-substring
@@ -154,21 +205,24 @@ interactively."
(save-excursion
(save-restriction
(widen)
- (goto-char (point-min))
+ (goto-char (copyright-start-point))
(copyright-update-year arg noquery)
- (goto-char (point-min))
+ (goto-char (copyright-start-point))
(and copyright-current-gpl-version
;; match the GPL version comment in .el files, including the
;; bilingual Esperanto one in two-column, and in texinfo.tex
- (re-search-forward
+ (copyright-re-search
"\\(the Free Software Foundation;\
either \\|; a\\^u eldono \\([0-9]+\\)a, ? a\\^u (la\\^u via \\)\
version \\([0-9]+\\), or (at"
- (if copyright-limit (+ (point) copyright-limit)) t)
- (not (string= (match-string 3) copyright-current-gpl-version))
+ (copyright-limit) t)
+ ;; Don't update if the file is already using a more recent
+ ;; version than the "current" one.
+ (< (string-to-number (match-string 3))
+ (string-to-number copyright-current-gpl-version))
(or noquery
- (y-or-n-p (concat "Replace GPL version by "
- copyright-current-gpl-version "? ")))
+ (y-or-n-p (format "Replace GPL version by %s? "
+ copyright-current-gpl-version)))
(progn
(if (match-end 2)
;; Esperanto bilingual comment in two-column.el
@@ -185,9 +239,8 @@ version \\([0-9]+\\), or (at"
Uses heuristic: year >= 50 means 19xx, < 50 means 20xx."
(interactive)
(widen)
- (goto-char (point-min))
- (if (re-search-forward copyright-regexp
- (if copyright-limit (+ (point) copyright-limit)) t)
+ (goto-char (copyright-start-point))
+ (if (copyright-re-search copyright-regexp (copyright-limit) t)
(let ((s (match-beginning 2))
(e (copy-marker (1+ (match-end 2))))
(p (make-marker))
@@ -211,7 +264,7 @@ Uses heuristic: year >= 50 means 19xx, < 50 means 20xx."
;; Don't mess up whitespace after the years.
(skip-chars-backward " \t")
(save-restriction
- (narrow-to-region (point-min) (point))
+ (narrow-to-region (copyright-start-point) (point))
(let ((fill-prefix " "))
(fill-region s last))))
(set-marker e nil)
@@ -227,15 +280,25 @@ Uses heuristic: year >= 50 means 19xx, < 50 means 20xx."
"Copyright (C) " `(substring (current-time-string) -4) " by "
(or (getenv "ORGANIZATION")
str)
- '(if (and copyright-limit (> (point) (+ (point-min) copyright-limit)))
+ '(if (copyright-offset-too-large-p)
(message "Copyright extends beyond `copyright-limit' and won't be updated automatically."))
comment-end \n)
+(defun copyright-update-directory (directory match)
+ "Update copyright notice for all files in DIRECTORY matching MATCH."
+ (interactive "DDirectory: \nMFilenames matching: ")
+ (dolist (file (directory-files directory t match nil))
+ (find-file file)
+ (let ((copyright-query nil))
+ (copyright-update))
+ (save-buffer)
+ (kill-buffer (current-buffer))))
+
(provide 'copyright)
;; For the copyright sign:
;; Local Variables:
-;; coding: emacs-mule
+;; coding: utf-8
;; End:
;; arch-tag: b4991afb-b6b1-4590-bebe-e076d9d4aee8