Initial Commit
[packages] / xemacs-packages / hyperbole / hlvar.el
1 ;;; hlvar.el --- Permits use of Hyperbole variables in local variable lists.
2
3 ;; Copyright (C) 1985-1995 Free Software Foundation, Inc.
4 ;; Developed with support from Motorola Inc.
5
6 ;; Author: Bob Weiner, Brown U.
7 ;; Maintainer: Mats Lidell <matsl@contactor.se>
8 ;; Keywords: extensions, hypermedia
9
10 ;; This file is part of GNU Hyperbole.
11
12 ;; GNU Hyperbole is free software; you can redistribute it and/or
13 ;; modify it under the terms of the GNU General Public License as
14 ;; published by the Free Software Foundation; either version 3, or (at
15 ;; your option) any later version.
16
17 ;; GNU Hyperbole is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ;; General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28 ;;
29 ;;   Hyperbole uses the colon character extensively in its variable names.
30 ;;   The standard GNU Emacs syntax for local variable setting does not allow
31 ;;   the use of this character, even though it is a valid symbol name
32 ;;   character.  The code here is slightly modified to support local setting of
33 ;;   variables with colons in their names.
34 ;;
35 ;;   Where the standard code allows: var:val
36 ;    This code requires one use:     var: val  (where var may include colons)
37 ;;
38 ;;   So functionality is gained and none is lost, but a slight incompatibility
39 ;;   in protocol is introduced.
40 ;;
41
42 ;;; Code:
43
44 ;;;
45 ;;; Public functions
46 ;;;
47
48 (defun hack-local-variables (&optional force)
49   "Parse, and bind or evaluate as appropriate, any local variables
50 for current buffer."
51   (if (fboundp 'hack-local-variables-prop-line)
52       (hack-local-variables-prop-line))
53   ;; Look for "Local variables:" line in last page.
54   (save-excursion
55     (goto-char (point-max))
56     (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
57     (let (local-start)
58       (if (let ((case-fold-search t)
59                 (ignore nil))
60             (and (search-forward "Local Variables:" nil t)
61                  (setq local-start (match-beginning 0))
62                  (or (and (not (string-match "^19\\." emacs-version))
63                           (not inhibit-local-variables))
64                      force
65                      (if (string-match "^19\\." emacs-version)
66                          (cond ((eq enable-local-variables t) t)
67                                ((eq enable-local-variables nil)
68                                 (setq ignore t))))
69                      (if ignore
70                          nil
71                        (save-window-excursion
72                          (switch-to-buffer (current-buffer))
73                          (save-excursion
74                            (beginning-of-line)
75                            (set-window-start (selected-window) (point)))
76                          (y-or-n-p
77                           (format "Set local variables as specified at end of %s? "
78                                   (file-name-nondirectory
79                                    buffer-file-name))))))))
80           (let ((continue t)
81                 prefix prefixlen suffix beg
82                 (enable-local-eval
83                  (if (boundp 'enable-local-eval) enable-local-eval)))
84             ;; The prefix is what comes before "local variables:" in its line.
85             ;; The suffix is what comes after "local variables:" in its line.
86             (skip-chars-forward " \t")
87             (or (eolp)
88                 (setq suffix (buffer-substring (point)
89                                                (progn (end-of-line) (point)))))
90             (goto-char local-start)
91             (or (bolp)
92                 (setq prefix
93                       (buffer-substring (point)
94                                         (progn (beginning-of-line) (point)))))
95
96             (if prefix (setq prefixlen (length prefix)
97                              prefix (regexp-quote prefix)))
98             (if suffix (setq suffix (concat (regexp-quote suffix) "$")))
99             (while continue
100               ;; Look at next local variable spec.
101               (if selective-display (re-search-forward "[\n\C-m]")
102                 (forward-line 1))
103               ;; Skip the prefix, if any.
104               (if prefix
105                   (if (looking-at prefix)
106                       (forward-char prefixlen)
107                     (error "Local variables entry is missing the prefix")))
108               ;; Find the variable name; strip whitespace.
109               (skip-chars-forward " \t")
110               (setq beg (point))
111               ;;
112               ;; Bob Weiner - changed here to allow colons in var names.
113               ;;
114               (skip-chars-forward "^ \t\n")
115               (skip-chars-backward ":")
116               (or (looking-at "[ \t]*:")
117                   (error "(hack-local-variables): Missing colon in local variables entry"))
118               ;;
119               ;; Bob Weiner - end changes.
120               ;;
121               (let* ((str (buffer-substring beg (point)))
122                      (var (read str))
123                      val)
124                 ;; Setting variable named "end" means end of list.
125                 (if (string-equal (downcase str) "end")
126                     (setq continue nil)
127                   ;; Otherwise read the variable value.
128                   (skip-chars-forward "^:")
129                   (forward-char 1)
130                   (setq val (read (current-buffer)))
131                   (skip-chars-backward "\n")
132                   (skip-chars-forward " \t")
133                   (or (if suffix (looking-at suffix) (eolp))
134                       (error "Local variables entry is terminated incorrectly"))
135                   ;; Set the variable.  "Variables" mode and eval are funny.
136                   (if (fboundp 'hack-one-local-variable)
137                       (hack-one-local-variable var val)
138                     (cond ((eq var 'mode)
139                            (funcall (intern (concat (downcase (symbol-name val))
140                                                     "-mode"))))
141                           ((eq var 'eval)
142                            (if (string= (user-login-name) "root")
143                                (message
144                                 "Ignoring `eval:' in file's local variables")
145                              (eval val)))
146                           (t (make-local-variable var)
147                              (set var val))))))))))
148     (run-hooks 'hack-local-variables-hook)))
149
150 \f 
151 ;; A new page avoids looking longer backwards for Local Variables
152 ;; section which gets confusing in this file.
153
154 (provide 'hlvar)
155
156 ;;; hlvar.el ends here