;;; -*- Mode:Emacs-Lisp -*-

;;;;;;;;;;;; I suspect rms is going to hate this one :-)
;;; "hide-copyleft.el" by Jamie Zawinski <jwz@lucid.com>, 19-jan-91.
;;;
;;; Not to belittle the importance of the presence of copyright notices on
;;; source code, but I sometimes find it tiresome to have fifteen lines of
;;; copyright notice at the beginning of each file.  Meta-< does not take you
;;; to the beginning of the code, it takes you a windowfull or two away, which
;;; can be tedious on slow terminal lines.
;;;
;;; I know what the copyright notice says; so this code makes all but the first
;;; line of it be invisible, by using Emacs's selective-display feature.  The
;;; text is still present and unmodified, but it is invisible.
;;;
;;; Elide the copyright notice with "Meta-X hide-copyleft-region".  Make it
;;; visible again with "Control-U Meta-X hide-copyleft-region".  Or, if
;;; you're absolutely certain you don't want to see the thing, you can do
;;; something like this in your .emacs file:
;;;
;;;        (autoload 'hide-copyleft-region "hide-copyleft" nil t)
;;;        (autoload 'unhide-copyleft-region "hide-copyleft" nil t)
;;;        (setq emacs-lisp-mode-hook 'hide-copyleft-region
;;;              c-mode-hook 'hide-copyleft-region)
;;;
;;; This code (obviously) has quite specific knowledge of the wording of the
;;; various CopyLefts I've run across.  Let me know if you find one on which
;;; it fails.
;;;
;;; This is free software; you can redistribute it blah blah blah.
;;; This notice must be preserved on all copies.
;;; (The preceeding text is only here to prevent this code form malfunctioning
;;; on the extremely pathological case of trying to hide the copyleft notice
;;; in a file which contains code for hiding copyleft notices but doesn't have
;;; one itself!)

(defun hide-copyleft-region (&optional arg)
  "Make the GNU CopyLeft notice invisible.  Unhide it again
with C-u \\[hide-copyleft-region]."
  (interactive "P")
  (if arg
      (unhide-copyleft-region)
    (save-excursion
     (save-restriction
      (if selective-display (error "selective-display is already on."))
      (catch 'Abort
	(let ((mod-p (buffer-modified-p))
	      (buffer-read-only nil)
	      start end max)
	  (widen)
	  (goto-char (point-min))
	  (or (search-forward "free software; you can redistribute it" nil t)
	      (search-forward "distributed in the hope that it will be useful,"
			      nil t)
	      (if (interactive-p)
		  (error "Couldn't find start of CopyLeft.")
		  (throw 'Abort nil)))
	  (forward-line 1)
	  (setq start (point))
	  (forward-line 30)
	  (setq max (point))
	  (goto-char start)
	  (or (search-forward "this notice must be preserved on all copies."
			      max t)
	      (and (search-forward "copy of the GNU General Public License"
				   max t)
		   (search-forward "02139," max t))
	      (error "Couldn't find end of CopyLeft."))
	  (forward-line 1)
	  ;; If the last line of the notice closes a C comment, don't
	  ;; hide that line to avoid confusion.
	  (if (save-excursion (forward-char -3) (looking-at "*/"))
	      (forward-line -1))
	  (setq end (point))
	  (goto-char start)
	  (while (< (point) end)
	    (delete-char -1)
	    (insert "\^M")
	    (forward-line 1))
	  (setq selective-display t)
	  (set-buffer-modified-p mod-p)))))))

(defun unhide-copyleft-region ()
  "If the GNU CopyLeft notice is elided, make it visible again."
  (save-excursion
    (save-restriction
      (widen)
      (goto-char (point-min))
      (let ((mod-p (buffer-modified-p))
	    (buffer-read-only nil)
	    end)
	(or (search-forward "free software; you can redistribute it" nil t)
	    (search-forward "distributed in the hope that it will be useful,"
			    nil t)
	    (error "Couldn't find start of CopyLeft."))
	(end-of-line)
	(setq end (point))
	(beginning-of-line)
	(while (search-forward "\^M" end t)
	  (delete-char -1)
	  (insert "\^J"))
	(set-buffer-modified-p mod-p)
	(setq selective-display nil)))))