home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / gnu / emacs / help / 3434 < prev    next >
Encoding:
Text File  |  1992-07-21  |  6.2 KB  |  165 lines

  1. Path: sparky!uunet!sun-barr!ames!elroy.jpl.nasa.gov!swrinde!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!src.bae.co.UK!moore
  2. From: moore@src.bae.co.UK (Chris Moore)
  3. Newsgroups: gnu.emacs.help
  4. Subject: making inhibit-local-variables selective:
  5. Message-ID: <9207211615.AA08424@sun19.src.bae.co.uk>
  6. Date: 21 Jul 92 16:15:51 GMT
  7. References: <1992Jul20.193852.28119@cs.cornell.edu>
  8. Sender: sjohnson@cis.ohio-state.edu (steven joseph johnson)
  9. Organization: Gatewayed from the GNU Project mailing list help-gnu-emacs@prep.ai.mit.edu
  10. Lines: 153
  11.  
  12.  
  13. raman@edu.cornell.cs (T. V. Raman) said:
  14.  
  15. > I normally set inhibit-local-variables to t to avoid nasty surprises.
  16.  
  17. Me too.
  18.  
  19. > Given this, is there any way I can specify that for certain files the
  20. > local variables are to be obeyed quietly?
  21.  
  22. The following code (probably) does this.  I had the same idea about a year
  23. ago, but never managed to get it working.  Seeing your message got me
  24. interested again.  I decided to go back and look at my code, with the
  25. experience of a year's elisp hacking, so now I have a working solution.
  26.  
  27. It's not particularly well tested (I only just got it working) but it seems
  28. to do what you want.  Please tell me whether it works for you, or if I've
  29. done anything stupid.
  30.  
  31. Chris.
  32. -----cut-----8<-----here-----8<--------------8<--------------
  33. ;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;
  34. ;; safe-local.el --- 
  35. ;; Author          : Chris Moore (moore@src.bae.co.uk)
  36. ;; Created On      : Tue Jul 21 16:31:35 1992
  37. ;; Last Modified By: Chris Moore
  38. ;; Last Modified On: Tue Jul 21 17:13:33 1992
  39. ;; Update Count    : 8
  40. ;; RCS             : $Id: safe-local.el,v 1.2 1992/07/21 16:14:09 moore Exp $
  41. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  42. ;;
  43. ;; This redefines hack-local-variables to silently accept the local
  44. ;; variables contained in any file whose path name matches any member of
  45. ;; the list safe-local-file-regexp-list.
  46. ;;
  47. ;; To install, place it in one of the directories specified in your
  48. ;; load-path, add (require 'safe-local) to your .emacs file and define the
  49. ;; list of regexps which are acceptable 'local variable' files, for example:
  50. ;;
  51. ;; (setq safe-local-file-regexp-list
  52. ;;     '("/home/aip1/moore/\\(\\.emacs\\|\\.zlogin\\|\\.zshenv\\|\\.zshrc\\)"
  53. ;;       "/gnu/src/\\(gcc\\|emacs\\).*"))
  54. ;;
  55. ;; in .emacs would mean that my zsh initialisation files and .emacs, along
  56. ;; with the entire emacs and gcc sources would be trusted to contain
  57. ;; sensible local variables.
  58. ;;
  59. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  60.  
  61. (require 'cl)
  62.  
  63. (defvar safe-local-file-regexp-list nil
  64.   "*Files which are trusted not to contain silly local variable definitions.")
  65.  
  66. ;; inhibit all except those we know to be good
  67. (setq inhibit-local-variables t)
  68.  
  69. (defun safe-re-member (item list)
  70.   "Similar to member, but uses string-match rather than eql.  Maintains the
  71. match-data."
  72.   (let ((data (match-data))
  73.     (ptr list)
  74.         (done nil)
  75.         (result '()))
  76.     (unwind-protect
  77.      (progn
  78.        (while (not (or done (endp ptr)))
  79.          (cond ((string-match (car ptr) item)
  80.             (setq done t)
  81.             (setq result ptr)))
  82.          (setq ptr (cdr ptr)))
  83.        result)
  84.       (store-match-data data))))
  85.  
  86. (defun hack-local-variables (&optional force)
  87.   "Parse, and bind or evaluate as appropriate, any local variables
  88. for current buffer."
  89.   ;; Look for "Local variables:" line in last page.
  90.   (save-excursion
  91.     (goto-char (point-max))
  92.     (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
  93.     (if (let ((case-fold-search t))
  94.       (and (search-forward "Local Variables:" nil t)
  95.            (or (not inhibit-local-variables)
  96.            force
  97.            (safe-re-member buffer-file-name safe-local-file-regexp-list)
  98.            (save-window-excursion
  99.              (switch-to-buffer (current-buffer))
  100.              (save-excursion
  101.                (beginning-of-line)
  102.                (set-window-start (selected-window) (point)))
  103.              (y-or-n-p (format "Set local variables as specified at end of %s? "
  104.                        (file-name-nondirectory buffer-file-name)))))))
  105.     (let ((continue t)
  106.           prefix prefixlen suffix beg)
  107.       ;; The prefix is what comes before "local variables:" in its line.
  108.       ;; The suffix is what comes after "local variables:" in its line.
  109.       (skip-chars-forward " \t")
  110.       (or (eolp)
  111.           (setq suffix (buffer-substring (point)
  112.                          (progn (end-of-line) (point)))))
  113.       (goto-char (match-beginning 0))
  114.       (or (bolp)
  115.           (setq prefix
  116.             (buffer-substring (point)
  117.                       (progn (beginning-of-line) (point)))))
  118.       (if prefix (setq prefixlen (length prefix)
  119.                prefix (regexp-quote prefix)))
  120.       (if suffix (setq suffix (concat (regexp-quote suffix) "$")))
  121.       (while continue
  122.         ;; Look at next local variable spec.
  123.         (if selective-display (re-search-forward "[\n\C-m]")
  124.           (forward-line 1))
  125.         ;; Skip the prefix, if any.
  126.         (if prefix
  127.         (if (looking-at prefix)
  128.             (forward-char prefixlen)
  129.           (error "Local variables entry is missing the prefix")))
  130.         ;; Find the variable name; strip whitespace.
  131.         (skip-chars-forward " \t")
  132.         (setq beg (point))
  133.         (skip-chars-forward "^:\n")
  134.         (if (eolp) (error "Missing colon in local variables entry"))
  135.         (skip-chars-backward " \t")
  136.         (let* ((str (buffer-substring beg (point)))
  137.            (var (read str))
  138.           val)
  139.           ;; Setting variable named "end" means end of list.
  140.           (if (string-equal (downcase str) "end")
  141.           (setq continue nil)
  142.         ;; Otherwise read the variable value.
  143.         (skip-chars-forward "^:")
  144.         (forward-char 1)
  145.         (setq val (read (current-buffer)))
  146.         (skip-chars-backward "\n")
  147.         (skip-chars-forward " \t")
  148.         (or (if suffix (looking-at suffix) (eolp))
  149.             (error "Local variables entry is terminated incorrectly"))
  150.         ;; Set the variable.  "Variables" mode and eval are funny.
  151.         (cond ((eq var 'mode)
  152.                (funcall (intern (concat (downcase (symbol-name val))
  153.                         "-mode"))))
  154.               ((eq var 'eval)
  155.                (if (string= (user-login-name) "root")
  156.                (message "Ignoring `eval:' in file's local variables")
  157.              (eval val)))
  158.               (t (make-local-variable var)
  159.              (set var val))))))))))
  160. ;--
  161. ;                        /      Chris Moore      \
  162. ; moore@src.bae.co.uk   / Sowerby Research Centre \   Kids, look!  Street crime!
  163. ; +44 272 363375        \  British Aerospace PLC  /        -- Homer Simpson
  164. ;                        \      BRISTOL, UK      /
  165.