Commit 0fe719e6 authored by Glenn Morris's avatar Glenn Morris

copyright.el updates.

* lisp/emacs-lisp/copyright.el (copyright-at-end-flag)
(copyright-names-regexp): Add safety properties.
(copyright-year-ranges): New option.
(copyright-find-end): New function, split from copyright-update-year.
(copyright-update-year): Use copyright-find-end.
(copyright-fix-years): Optionally, convert years to ranges.
Handle years continued over comment lines.
Do not mess with the fill-prefix.
Do not call copyright-update.
(copyright-update-directory): Optionally, fix years rather than update.
Skip directories.  Find files literally, with only safe local vars.

* etc/NEWS: Mention copyright-fix-years and ranges.
parent d0cb8662
......@@ -607,6 +607,11 @@ means to prompt the user for command specifics, e.g. a merge location.
**** Currently supported by Bzr.
** Miscellaneous
---
*** `copyright-fix-years' can optionally convert consecutive years to ranges.
* New Modes and Packages in Emacs 24.1
......
2011-01-25 Glenn Morris <rgm@gnu.org>
* emacs-lisp/copyright.el (copyright-at-end-flag)
(copyright-names-regexp): Add safety properties.
(copyright-year-ranges): New option.
(copyright-find-end): New function, split from copyright-update-year.
(copyright-update-year): Use copyright-find-end.
(copyright-fix-years): Optionally, convert years to ranges.
Handle years continued over comment lines.
Do not mess with the fill-prefix.
Do not call copyright-update.
(copyright-update-directory): Optionally, fix years rather than update.
Skip directories. Find files literally, with only safe local vars.
2011-01-25 Stefan Monnier <monnier@iro.umontreal.ca>
* files.el (file-name-non-special): Only change buffer-file-name after
......
;;; copyright.el --- update the copyright notice in current buffer
;; Copyright (C) 1991-1995, 1998, 2001-2011
;; Free Software Foundation, Inc.
;; Copyright (C) 1991-1995, 1998, 2001-2011 Free Software Foundation, Inc.
;; Author: Daniel Pfeiffer <occitan@esperanto.org>
;; Keywords: maint, tools
......@@ -47,6 +46,7 @@ This is useful for ChangeLogs."
:group 'copyright
:type 'boolean
:version "23.1")
;;;###autoload(put 'copyright-at-end-flag 'safe-local-variable 'booleanp)
(defcustom copyright-regexp
"\\(©\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\
......@@ -66,6 +66,11 @@ someone else or to a group for which you do not work."
:group 'copyright
:type 'regexp)
;; The worst that can happen is a malicious regexp that overflows in
;; the regexp matcher, a minor nuisance. It's a pain to be always
;; prompted if you want to put this in a dir-locals.el.
;;;###autoload(put 'copyright-names-regexp 'safe-local-variable 'stringp)
(defcustom copyright-years-regexp
"\\(\\s *\\)\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
"Match additional copyright notice years.
......@@ -73,6 +78,19 @@ The second \\( \\) construct must match the years."
:group 'copyright
:type 'regexp)
;; See "Copyright Notices" in maintain.info.
;; TODO? 'end only for ranges at the end, other for all ranges.
;; Minimum limit on the size of a range?
(defcustom copyright-year-ranges nil
"Non-nil if individual consecutive years should be replaced with a range.
For example: 2005, 2006, 2007, 2008 might be replaced with 2005-2008.
If you use ranges, you should add an explanatory note in a README file.
The function `copyright-fix-year' respects this variable."
:group 'copyright
:type 'boolean
:version "24.1")
;;;###autoload(put 'copyright-year-ranges 'safe-local-variable 'booleanp)
(defcustom copyright-query 'function
"If non-nil, ask user before changing copyright.
......@@ -139,11 +157,10 @@ This function sets the match-data that `copyright-update-year' uses."
;; such an error is very inconvenient for the user.
(error (message "Can't update copyright: %s" err) nil)))
(defun copyright-update-year (replace noquery)
;; This uses the match-data from copyright-find-copyright.
(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.
(defun copyright-find-end ()
"Possibly adjust the search performed by `copyright-find-copyright'.
If the years continue onto multiple lines that are marked as comments,
skips to the end of all the years."
(while (save-excursion
(and (eq (following-char) ?,)
(progn (forward-char 1) t)
......@@ -158,8 +175,12 @@ This function sets the match-data that `copyright-update-year' uses."
(re-search-forward comment-start-skip)
;; (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)))
(re-search-forward (format "\\(%s\\)" copyright-years-regexp))))
(defun copyright-update-year (replace noquery)
;; This uses the match-data from copyright-find-copyright/end.
(goto-char (match-end 1))
(copyright-find-end)
;; Note that `current-time-string' isn't locale-sensitive.
(setq copyright-current-year (substring (current-time-string) -4))
(unless (string= (buffer-substring (- (match-end 3) 2) (match-end 3))
......@@ -217,6 +238,7 @@ interactively."
(save-restriction
;; If names-regexp doesn't match, we should not mess with
;; the years _or_ the GPL version.
;; TODO there may be multiple copyrights we should update.
(when (copyright-find-copyright)
(copyright-update-year arg noquery)
(goto-char (copyright-start-point))
......@@ -246,42 +268,78 @@ interactively."
nil))
;; FIXME should be within 50 years of present (cf calendar).
;; FIXME heuristic should be within 50 years of present (cf calendar).
;;;###autoload
(defun copyright-fix-years ()
"Convert 2 digit years to 4 digit years.
Uses heuristic: year >= 50 means 19xx, < 50 means 20xx."
Uses heuristic: year >= 50 means 19xx, < 50 means 20xx.
If `copyright-year-ranges' (which see) is non-nil, also
independently replaces consecutive years with a range."
(interactive)
;; TODO there may be multiple copyrights we should fix.
(if (copyright-find-copyright)
(let ((s (match-beginning 2))
(e (copy-marker (1+ (match-end 2))))
(let ((s (match-beginning 3))
(p (make-marker))
last)
;; Not line-beg-pos, so we don't mess up leading whitespace.
(copystart (match-beginning 0))
e last sep year prev-year first-year range-start range-end)
;; In case years are continued over multiple, commented lines.
(goto-char (match-end 1))
(copyright-find-end)
(setq e (copy-marker (1+ (match-end 3))))
(goto-char s)
(while (re-search-forward "[0-9]+" e t)
(set-marker p (point))
(goto-char (match-beginning 0))
(let ((sep (char-before))
(year (string-to-number (match-string 0))))
(when (and sep
(/= (char-syntax sep) ?\s)
(/= sep ?-))
(insert " "))
(when (< year 100)
(insert (if (>= year 50) "19" "20"))))
(setq year (string-to-number (match-string 0)))
(and (setq sep (char-before))
(/= (char-syntax sep) ?\s)
(/= sep ?-)
(insert " "))
(when (< year 100)
(insert (if (>= year 50) "19" "20"))
(setq year (+ year (if (>= year 50) 1900 2000))))
(goto-char p)
(setq last p))
(when copyright-year-ranges
;; If the previous thing was a range, don't try to tack more on.
;; Ie not 2000-2005 -> 2000-2005-2007
;; TODO should merge into existing range if possible.
(if (eq sep ?-)
(setq prev-year nil
year nil)
(if (and prev-year (= year (1+ prev-year)))
(setq range-end (point))
(when (and first-year prev-year
(> prev-year first-year))
(goto-char range-end)
(delete-region range-start range-end)
(insert (format "-%d" prev-year))
(goto-char p))
(setq first-year year
range-start (point)))))
(setq prev-year year
last p))
(when last
(when (and copyright-year-ranges
first-year prev-year
(> prev-year first-year))
(goto-char range-end)
(delete-region range-start range-end)
(insert (format "-%d" prev-year)))
(goto-char last)
;; Don't mess up whitespace after the years.
(skip-chars-backward " \t")
(save-restriction
(narrow-to-region (copyright-start-point) (point))
(let ((fill-prefix " "))
(fill-region s last))))
(save-restriction
(narrow-to-region copystart (point))
;; This is clearly wrong, eg what about comment markers?
;;; (let ((fill-prefix " "))
;; TODO do not break copyright owner over lines.
(fill-region (point-min) (point-max))))
(set-marker e nil)
(set-marker p nil)
(copyright-update nil t))
(set-marker p nil))
;; Simply reformatting the years is not copyrightable, so it does
;; not seem right to call this. Also it messes with ranges.
;;; (copyright-update nil t))
(message "No copyright message")))
;;;###autoload
......@@ -296,17 +354,24 @@ Uses heuristic: year >= 50 means 19xx, < 50 means 20xx."
(message "Copyright extends beyond `copyright-limit' and won't be updated automatically."))
comment-end \n)
;; TODO: recurse, exclude COPYING etc.
;;;###autoload
(defun copyright-update-directory (directory match)
"Update copyright notice for all files in DIRECTORY matching MATCH."
(defun copyright-update-directory (directory match &optional fix)
"Update copyright notice for all files in DIRECTORY matching MATCH.
If FIX is non-nil, run `copyright-fix-years' instead."
(interactive "DDirectory: \nMFilenames matching (regexp): ")
(dolist (file (directory-files directory t match nil))
(message "Updating file `%s'" file)
(find-file file)
(let ((copyright-query nil))
(copyright-update))
(save-buffer)
(kill-buffer (current-buffer))))
(unless (file-directory-p file)
(message "Updating file `%s'" file)
(find-file-literally file)
(let ((inhibit-read-only t)
(enable-local-variables :safe)
copyright-query)
(if fix
(copyright-fix-years)
(copyright-update)))
(save-buffer)
(kill-buffer (current-buffer)))))
(provide 'copyright)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment