diff options
| author | Glenn Morris | 2011-01-25 00:36:34 -0800 |
|---|---|---|
| committer | Glenn Morris | 2011-01-25 00:36:34 -0800 |
| commit | 0fe719e691955e8e4a7f5bc74ed981b2e8ca17ce (patch) | |
| tree | e51b35f061a107899cfb14205c424067f53d846e | |
| parent | d0cb866238b3a7ab811ed666d21e8bd97f6f3b41 (diff) | |
| download | emacs-0fe719e691955e8e4a7f5bc74ed981b2e8ca17ce.tar.gz emacs-0fe719e691955e8e4a7f5bc74ed981b2e8ca17ce.zip | |
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.
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | lisp/ChangeLog | 14 | ||||
| -rw-r--r-- | lisp/emacs-lisp/copyright.el | 137 |
3 files changed, 120 insertions, 36 deletions
| @@ -607,6 +607,11 @@ means to prompt the user for command specifics, e.g. a merge location. | |||
| 607 | 607 | ||
| 608 | **** Currently supported by Bzr. | 608 | **** Currently supported by Bzr. |
| 609 | 609 | ||
| 610 | ** Miscellaneous | ||
| 611 | |||
| 612 | --- | ||
| 613 | *** `copyright-fix-years' can optionally convert consecutive years to ranges. | ||
| 614 | |||
| 610 | 615 | ||
| 611 | * New Modes and Packages in Emacs 24.1 | 616 | * New Modes and Packages in Emacs 24.1 |
| 612 | 617 | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5b4b0dcc2d3..4d758d4bb18 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2011-01-25 Glenn Morris <rgm@gnu.org> | ||
| 2 | |||
| 3 | * emacs-lisp/copyright.el (copyright-at-end-flag) | ||
| 4 | (copyright-names-regexp): Add safety properties. | ||
| 5 | (copyright-year-ranges): New option. | ||
| 6 | (copyright-find-end): New function, split from copyright-update-year. | ||
| 7 | (copyright-update-year): Use copyright-find-end. | ||
| 8 | (copyright-fix-years): Optionally, convert years to ranges. | ||
| 9 | Handle years continued over comment lines. | ||
| 10 | Do not mess with the fill-prefix. | ||
| 11 | Do not call copyright-update. | ||
| 12 | (copyright-update-directory): Optionally, fix years rather than update. | ||
| 13 | Skip directories. Find files literally, with only safe local vars. | ||
| 14 | |||
| 1 | 2011-01-25 Stefan Monnier <monnier@iro.umontreal.ca> | 15 | 2011-01-25 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 16 | ||
| 3 | * files.el (file-name-non-special): Only change buffer-file-name after | 17 | * files.el (file-name-non-special): Only change buffer-file-name after |
diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el index 54a9437e649..cf5a48b5a29 100644 --- a/lisp/emacs-lisp/copyright.el +++ b/lisp/emacs-lisp/copyright.el | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | ;;; copyright.el --- update the copyright notice in current buffer | 1 | ;;; copyright.el --- update the copyright notice in current buffer |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1991-1995, 1998, 2001-2011 | 3 | ;; Copyright (C) 1991-1995, 1998, 2001-2011 Free Software Foundation, Inc. |
| 4 | ;; Free Software Foundation, Inc. | ||
| 5 | 4 | ||
| 6 | ;; Author: Daniel Pfeiffer <occitan@esperanto.org> | 5 | ;; Author: Daniel Pfeiffer <occitan@esperanto.org> |
| 7 | ;; Keywords: maint, tools | 6 | ;; Keywords: maint, tools |
| @@ -47,6 +46,7 @@ This is useful for ChangeLogs." | |||
| 47 | :group 'copyright | 46 | :group 'copyright |
| 48 | :type 'boolean | 47 | :type 'boolean |
| 49 | :version "23.1") | 48 | :version "23.1") |
| 49 | ;;;###autoload(put 'copyright-at-end-flag 'safe-local-variable 'booleanp) | ||
| 50 | 50 | ||
| 51 | (defcustom copyright-regexp | 51 | (defcustom copyright-regexp |
| 52 | "\\(©\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\ | 52 | "\\(©\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\ |
| @@ -66,6 +66,11 @@ someone else or to a group for which you do not work." | |||
| 66 | :group 'copyright | 66 | :group 'copyright |
| 67 | :type 'regexp) | 67 | :type 'regexp) |
| 68 | 68 | ||
| 69 | ;; The worst that can happen is a malicious regexp that overflows in | ||
| 70 | ;; the regexp matcher, a minor nuisance. It's a pain to be always | ||
| 71 | ;; prompted if you want to put this in a dir-locals.el. | ||
| 72 | ;;;###autoload(put 'copyright-names-regexp 'safe-local-variable 'stringp) | ||
| 73 | |||
| 69 | (defcustom copyright-years-regexp | 74 | (defcustom copyright-years-regexp |
| 70 | "\\(\\s *\\)\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)" | 75 | "\\(\\s *\\)\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)" |
| 71 | "Match additional copyright notice years. | 76 | "Match additional copyright notice years. |
| @@ -73,6 +78,19 @@ The second \\( \\) construct must match the years." | |||
| 73 | :group 'copyright | 78 | :group 'copyright |
| 74 | :type 'regexp) | 79 | :type 'regexp) |
| 75 | 80 | ||
| 81 | ;; See "Copyright Notices" in maintain.info. | ||
| 82 | ;; TODO? 'end only for ranges at the end, other for all ranges. | ||
| 83 | ;; Minimum limit on the size of a range? | ||
| 84 | (defcustom copyright-year-ranges nil | ||
| 85 | "Non-nil if individual consecutive years should be replaced with a range. | ||
| 86 | For example: 2005, 2006, 2007, 2008 might be replaced with 2005-2008. | ||
| 87 | If you use ranges, you should add an explanatory note in a README file. | ||
| 88 | The function `copyright-fix-year' respects this variable." | ||
| 89 | :group 'copyright | ||
| 90 | :type 'boolean | ||
| 91 | :version "24.1") | ||
| 92 | |||
| 93 | ;;;###autoload(put 'copyright-year-ranges 'safe-local-variable 'booleanp) | ||
| 76 | 94 | ||
| 77 | (defcustom copyright-query 'function | 95 | (defcustom copyright-query 'function |
| 78 | "If non-nil, ask user before changing copyright. | 96 | "If non-nil, ask user before changing copyright. |
| @@ -139,11 +157,10 @@ This function sets the match-data that `copyright-update-year' uses." | |||
| 139 | ;; such an error is very inconvenient for the user. | 157 | ;; such an error is very inconvenient for the user. |
| 140 | (error (message "Can't update copyright: %s" err) nil))) | 158 | (error (message "Can't update copyright: %s" err) nil))) |
| 141 | 159 | ||
| 142 | (defun copyright-update-year (replace noquery) | 160 | (defun copyright-find-end () |
| 143 | ;; This uses the match-data from copyright-find-copyright. | 161 | "Possibly adjust the search performed by `copyright-find-copyright'. |
| 144 | (goto-char (match-end 1)) | 162 | If the years continue onto multiple lines that are marked as comments, |
| 145 | ;; If the years are continued onto multiple lines | 163 | skips to the end of all the years." |
| 146 | ;; that are marked as comments, skip to the end of the years anyway. | ||
| 147 | (while (save-excursion | 164 | (while (save-excursion |
| 148 | (and (eq (following-char) ?,) | 165 | (and (eq (following-char) ?,) |
| 149 | (progn (forward-char 1) t) | 166 | (progn (forward-char 1) t) |
| @@ -158,8 +175,12 @@ This function sets the match-data that `copyright-update-year' uses." | |||
| 158 | (re-search-forward comment-start-skip) | 175 | (re-search-forward comment-start-skip) |
| 159 | ;; (2) Need the extra \\( \\) so that the years are subexp 3, as | 176 | ;; (2) Need the extra \\( \\) so that the years are subexp 3, as |
| 160 | ;; they are at note (1) above. | 177 | ;; they are at note (1) above. |
| 161 | (re-search-forward (format "\\(%s\\)" copyright-years-regexp))) | 178 | (re-search-forward (format "\\(%s\\)" copyright-years-regexp)))) |
| 162 | 179 | ||
| 180 | (defun copyright-update-year (replace noquery) | ||
| 181 | ;; This uses the match-data from copyright-find-copyright/end. | ||
| 182 | (goto-char (match-end 1)) | ||
| 183 | (copyright-find-end) | ||
| 163 | ;; Note that `current-time-string' isn't locale-sensitive. | 184 | ;; Note that `current-time-string' isn't locale-sensitive. |
| 164 | (setq copyright-current-year (substring (current-time-string) -4)) | 185 | (setq copyright-current-year (substring (current-time-string) -4)) |
| 165 | (unless (string= (buffer-substring (- (match-end 3) 2) (match-end 3)) | 186 | (unless (string= (buffer-substring (- (match-end 3) 2) (match-end 3)) |
| @@ -217,6 +238,7 @@ interactively." | |||
| 217 | (save-restriction | 238 | (save-restriction |
| 218 | ;; If names-regexp doesn't match, we should not mess with | 239 | ;; If names-regexp doesn't match, we should not mess with |
| 219 | ;; the years _or_ the GPL version. | 240 | ;; the years _or_ the GPL version. |
| 241 | ;; TODO there may be multiple copyrights we should update. | ||
| 220 | (when (copyright-find-copyright) | 242 | (when (copyright-find-copyright) |
| 221 | (copyright-update-year arg noquery) | 243 | (copyright-update-year arg noquery) |
| 222 | (goto-char (copyright-start-point)) | 244 | (goto-char (copyright-start-point)) |
| @@ -246,42 +268,78 @@ interactively." | |||
| 246 | nil)) | 268 | nil)) |
| 247 | 269 | ||
| 248 | 270 | ||
| 249 | ;; FIXME should be within 50 years of present (cf calendar). | 271 | ;; FIXME heuristic should be within 50 years of present (cf calendar). |
| 250 | ;;;###autoload | 272 | ;;;###autoload |
| 251 | (defun copyright-fix-years () | 273 | (defun copyright-fix-years () |
| 252 | "Convert 2 digit years to 4 digit years. | 274 | "Convert 2 digit years to 4 digit years. |
| 253 | Uses heuristic: year >= 50 means 19xx, < 50 means 20xx." | 275 | Uses heuristic: year >= 50 means 19xx, < 50 means 20xx. |
| 276 | If `copyright-year-ranges' (which see) is non-nil, also | ||
| 277 | independently replaces consecutive years with a range." | ||
| 254 | (interactive) | 278 | (interactive) |
| 279 | ;; TODO there may be multiple copyrights we should fix. | ||
| 255 | (if (copyright-find-copyright) | 280 | (if (copyright-find-copyright) |
| 256 | (let ((s (match-beginning 2)) | 281 | (let ((s (match-beginning 3)) |
| 257 | (e (copy-marker (1+ (match-end 2)))) | ||
| 258 | (p (make-marker)) | 282 | (p (make-marker)) |
| 259 | last) | 283 | ;; Not line-beg-pos, so we don't mess up leading whitespace. |
| 284 | (copystart (match-beginning 0)) | ||
| 285 | e last sep year prev-year first-year range-start range-end) | ||
| 286 | ;; In case years are continued over multiple, commented lines. | ||
| 287 | (goto-char (match-end 1)) | ||
| 288 | (copyright-find-end) | ||
| 289 | (setq e (copy-marker (1+ (match-end 3)))) | ||
| 260 | (goto-char s) | 290 | (goto-char s) |
| 261 | (while (re-search-forward "[0-9]+" e t) | 291 | (while (re-search-forward "[0-9]+" e t) |
| 262 | (set-marker p (point)) | 292 | (set-marker p (point)) |
| 263 | (goto-char (match-beginning 0)) | 293 | (goto-char (match-beginning 0)) |
| 264 | (let ((sep (char-before)) | 294 | (setq year (string-to-number (match-string 0))) |
| 265 | (year (string-to-number (match-string 0)))) | 295 | (and (setq sep (char-before)) |
| 266 | (when (and sep | 296 | (/= (char-syntax sep) ?\s) |
| 267 | (/= (char-syntax sep) ?\s) | 297 | (/= sep ?-) |
| 268 | (/= sep ?-)) | 298 | (insert " ")) |
| 269 | (insert " ")) | 299 | (when (< year 100) |
| 270 | (when (< year 100) | 300 | (insert (if (>= year 50) "19" "20")) |
| 271 | (insert (if (>= year 50) "19" "20")))) | 301 | (setq year (+ year (if (>= year 50) 1900 2000)))) |
| 272 | (goto-char p) | 302 | (goto-char p) |
| 273 | (setq last p)) | 303 | (when copyright-year-ranges |
| 304 | ;; If the previous thing was a range, don't try to tack more on. | ||
| 305 | ;; Ie not 2000-2005 -> 2000-2005-2007 | ||
| 306 | ;; TODO should merge into existing range if possible. | ||
| 307 | (if (eq sep ?-) | ||
| 308 | (setq prev-year nil | ||
| 309 | year nil) | ||
| 310 | (if (and prev-year (= year (1+ prev-year))) | ||
| 311 | (setq range-end (point)) | ||
| 312 | (when (and first-year prev-year | ||
| 313 | (> prev-year first-year)) | ||
| 314 | (goto-char range-end) | ||
| 315 | (delete-region range-start range-end) | ||
| 316 | (insert (format "-%d" prev-year)) | ||
| 317 | (goto-char p)) | ||
| 318 | (setq first-year year | ||
| 319 | range-start (point))))) | ||
| 320 | (setq prev-year year | ||
| 321 | last p)) | ||
| 274 | (when last | 322 | (when last |
| 323 | (when (and copyright-year-ranges | ||
| 324 | first-year prev-year | ||
| 325 | (> prev-year first-year)) | ||
| 326 | (goto-char range-end) | ||
| 327 | (delete-region range-start range-end) | ||
| 328 | (insert (format "-%d" prev-year))) | ||
| 275 | (goto-char last) | 329 | (goto-char last) |
| 276 | ;; Don't mess up whitespace after the years. | 330 | ;; Don't mess up whitespace after the years. |
| 277 | (skip-chars-backward " \t") | 331 | (skip-chars-backward " \t") |
| 278 | (save-restriction | 332 | (save-restriction |
| 279 | (narrow-to-region (copyright-start-point) (point)) | 333 | (narrow-to-region copystart (point)) |
| 280 | (let ((fill-prefix " ")) | 334 | ;; This is clearly wrong, eg what about comment markers? |
| 281 | (fill-region s last)))) | 335 | ;;; (let ((fill-prefix " ")) |
| 336 | ;; TODO do not break copyright owner over lines. | ||
| 337 | (fill-region (point-min) (point-max)))) | ||
| 282 | (set-marker e nil) | 338 | (set-marker e nil) |
| 283 | (set-marker p nil) | 339 | (set-marker p nil)) |
| 284 | (copyright-update nil t)) | 340 | ;; Simply reformatting the years is not copyrightable, so it does |
| 341 | ;; not seem right to call this. Also it messes with ranges. | ||
| 342 | ;;; (copyright-update nil t)) | ||
| 285 | (message "No copyright message"))) | 343 | (message "No copyright message"))) |
| 286 | 344 | ||
| 287 | ;;;###autoload | 345 | ;;;###autoload |
| @@ -296,17 +354,24 @@ Uses heuristic: year >= 50 means 19xx, < 50 means 20xx." | |||
| 296 | (message "Copyright extends beyond `copyright-limit' and won't be updated automatically.")) | 354 | (message "Copyright extends beyond `copyright-limit' and won't be updated automatically.")) |
| 297 | comment-end \n) | 355 | comment-end \n) |
| 298 | 356 | ||
| 357 | ;; TODO: recurse, exclude COPYING etc. | ||
| 299 | ;;;###autoload | 358 | ;;;###autoload |
| 300 | (defun copyright-update-directory (directory match) | 359 | (defun copyright-update-directory (directory match &optional fix) |
| 301 | "Update copyright notice for all files in DIRECTORY matching MATCH." | 360 | "Update copyright notice for all files in DIRECTORY matching MATCH. |
| 361 | If FIX is non-nil, run `copyright-fix-years' instead." | ||
| 302 | (interactive "DDirectory: \nMFilenames matching (regexp): ") | 362 | (interactive "DDirectory: \nMFilenames matching (regexp): ") |
| 303 | (dolist (file (directory-files directory t match nil)) | 363 | (dolist (file (directory-files directory t match nil)) |
| 304 | (message "Updating file `%s'" file) | 364 | (unless (file-directory-p file) |
| 305 | (find-file file) | 365 | (message "Updating file `%s'" file) |
| 306 | (let ((copyright-query nil)) | 366 | (find-file-literally file) |
| 307 | (copyright-update)) | 367 | (let ((inhibit-read-only t) |
| 308 | (save-buffer) | 368 | (enable-local-variables :safe) |
| 309 | (kill-buffer (current-buffer)))) | 369 | copyright-query) |
| 370 | (if fix | ||
| 371 | (copyright-fix-years) | ||
| 372 | (copyright-update))) | ||
| 373 | (save-buffer) | ||
| 374 | (kill-buffer (current-buffer))))) | ||
| 310 | 375 | ||
| 311 | (provide 'copyright) | 376 | (provide 'copyright) |
| 312 | 377 | ||