diff options
| author | Chong Yidong | 2006-02-14 01:21:31 +0000 |
|---|---|---|
| committer | Chong Yidong | 2006-02-14 01:21:31 +0000 |
| commit | 5a6c1d871eb47630435c4253286f550e9c91b0eb (patch) | |
| tree | 6e0ec2654ed83d951aec29dff7b479889135e433 | |
| parent | 240029d92c295507f17ceb6e9d30b93610bc4deb (diff) | |
| download | emacs-5a6c1d871eb47630435c4253286f550e9c91b0eb.tar.gz emacs-5a6c1d871eb47630435c4253286f550e9c91b0eb.zip | |
* files.el (safe-local-variable-values): New option.
(hack-local-variables-prop-line): Return a list of variable-value
pairs if MODE-ONLY is non-nil.
(hack-local-variables): Construct list of variable-value pairs,
and apply or reject them in one go. Ask for confirmation if
variables are not known safe.
(hack-local-variables-confirm): Complete rewrite. Support
`safe-local-variable-values'.
(enable-local-variables): Update docstring to reflect new
behavior.
(ignored-local-variables): Ignore ignored-local-variables and
safe-local-variable-values.
(safe-local-variable-p): New function.
(risky-local-variable-p): `safe-local-variable' property check
moved to safe-local-variable-p.
(hack-one-local-variable): Checks moved to hack-local-variables.
(byte-compile-dynamic, c-basic-offset, c-file-style,
c-indent-level, comment-column, fill-column, fill-prefix,
indent-tabs-mode, kept-new-versions, no-byte-compile,
no-update-autoloads, outline-regexp, page-delimiter,
paragraph-start, paragraph-separate, sentence-end,
sentence-end-double-space tab-width, version-control): Add
`safe-local-variable' property.
* find-lisp.el: Delete nonexistent `autocompile' file variable.
* icomplete.el, play/landmark.el: Change nonexistent
`outline-layout' file variable to `allout-layout'.
| -rw-r--r-- | lisp/ChangeLog | 32 | ||||
| -rw-r--r-- | lisp/files.el | 452 | ||||
| -rw-r--r-- | lisp/find-lisp.el | 4 | ||||
| -rw-r--r-- | lisp/icomplete.el | 2 | ||||
| -rw-r--r-- | lisp/play/landmark.el | 4 |
5 files changed, 308 insertions, 186 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6ccf48732b4..83e47bfc26d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,35 @@ | |||
| 1 | 2006-02-13 Chong Yidong <cyd@stupidchicken.com> | ||
| 2 | |||
| 3 | * files.el (safe-local-variable-values): New option. | ||
| 4 | (hack-local-variables-prop-line): Return a list of variable-value | ||
| 5 | pairs if MODE-ONLY is non-nil. | ||
| 6 | (hack-local-variables): Construct list of variable-value pairs, | ||
| 7 | and apply or reject them in one go. Ask for confirmation if | ||
| 8 | variables are not known safe. | ||
| 9 | (hack-local-variables-confirm): Complete rewrite. Support | ||
| 10 | `safe-local-variable-values'. | ||
| 11 | (enable-local-variables): Update docstring to reflect new | ||
| 12 | behavior. | ||
| 13 | (ignored-local-variables): Ignore ignored-local-variables and | ||
| 14 | safe-local-variable-values. | ||
| 15 | (safe-local-variable-p): New function. | ||
| 16 | (risky-local-variable-p): `safe-local-variable' property check | ||
| 17 | moved to safe-local-variable-p. | ||
| 18 | (hack-one-local-variable): Checks moved to hack-local-variables. | ||
| 19 | |||
| 20 | (byte-compile-dynamic, c-basic-offset, c-file-style, | ||
| 21 | c-indent-level, comment-column, fill-column, fill-prefix, | ||
| 22 | indent-tabs-mode, kept-new-versions, no-byte-compile, | ||
| 23 | no-update-autoloads, outline-regexp, page-delimiter, | ||
| 24 | paragraph-start, paragraph-separate, sentence-end, | ||
| 25 | sentence-end-double-space tab-width, version-control): Add | ||
| 26 | `safe-local-variable' property. | ||
| 27 | |||
| 28 | * find-lisp.el: Delete nonexistent `autocompile' file variable. | ||
| 29 | |||
| 30 | * icomplete.el, play/landmark.el: Change nonexistent | ||
| 31 | `outline-layout' file variable to `allout-layout'. | ||
| 32 | |||
| 1 | 2006-02-14 Nick Roberts <nickrob@snap.net.nz> | 33 | 2006-02-14 Nick Roberts <nickrob@snap.net.nz> |
| 2 | 34 | ||
| 3 | * progmodes/gdb-ui.el (gud-watch, gdb-invalidate-registers-1) | 35 | * progmodes/gdb-ui.el (gud-watch, gdb-invalidate-registers-1) |
diff --git a/lisp/files.el b/lisp/files.el index 16229cfda1c..e96aace0467 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -445,8 +445,13 @@ use `before-save-hook'.") | |||
| 445 | (defcustom enable-local-variables t | 445 | (defcustom enable-local-variables t |
| 446 | "*Control use of local variables in files you visit. | 446 | "*Control use of local variables in files you visit. |
| 447 | The value can be t, nil or something else. | 447 | The value can be t, nil or something else. |
| 448 | A value of t means file local variables specifications are obeyed; | 448 | |
| 449 | nil means they are ignored; anything else means query. | 449 | A value of t means file local variables specifications are obeyed |
| 450 | if all the specified variables are safe. If any variables are | ||
| 451 | not safe, you will be queries before setting them. | ||
| 452 | A value of nil means file local variables are ignored. | ||
| 453 | Any other value means to always query. | ||
| 454 | |||
| 450 | This variable also controls use of major modes specified in | 455 | This variable also controls use of major modes specified in |
| 451 | a -*- line. | 456 | a -*- line. |
| 452 | 457 | ||
| @@ -2214,42 +2219,79 @@ Otherwise, return nil; point may be changed." | |||
| 2214 | (goto-char beg) | 2219 | (goto-char beg) |
| 2215 | end)))) | 2220 | end)))) |
| 2216 | 2221 | ||
| 2217 | (defun hack-local-variables-confirm (string flag-to-check) | 2222 | (defun hack-local-variables-confirm (vars unsafe-vars risky-vars) |
| 2218 | (or (eq flag-to-check t) | 2223 | (if noninteractive |
| 2219 | (and flag-to-check | 2224 | nil |
| 2220 | (save-window-excursion | 2225 | (let ((name (if buffer-file-name |
| 2221 | (condition-case nil | 2226 | (file-name-nondirectory buffer-file-name) |
| 2222 | (switch-to-buffer (current-buffer)) | 2227 | (concat "buffer " (buffer-name)))) |
| 2223 | (error | 2228 | char) |
| 2224 | ;; If we fail to switch in the selected window, | 2229 | (save-window-excursion |
| 2225 | ;; it is probably a minibuffer or dedicated window. | 2230 | (with-output-to-temp-buffer "*Local Variables*" |
| 2226 | ;; So try another window. | 2231 | (if unsafe-vars |
| 2227 | (let ((pop-up-frames nil)) | 2232 | (progn (princ "The local variables list in ") |
| 2228 | ;; Refrain from popping up frames since it can't | 2233 | (princ name) |
| 2229 | ;; be undone by save-window-excursion. | 2234 | (princ "\ncontains values that may not be safe (*)") |
| 2230 | (pop-to-buffer (current-buffer))))) | 2235 | (if risky-vars |
| 2231 | (save-excursion | 2236 | (princ ", and variables that are risky (**).") |
| 2232 | (beginning-of-line) | 2237 | (princ "."))) |
| 2233 | (set-window-start (selected-window) (point))) | 2238 | (if risky-vars |
| 2234 | (y-or-n-p (format string | 2239 | (progn (princ "The local variables list in ") |
| 2235 | (if buffer-file-name | 2240 | (princ name) |
| 2236 | (file-name-nondirectory buffer-file-name) | 2241 | (princ "\ncontains variables that are risky (**).")) |
| 2237 | (concat "buffer " (buffer-name))))))))) | 2242 | (princ "A local variables list is specified in ") |
| 2243 | (princ name) | ||
| 2244 | (princ "."))) | ||
| 2245 | (princ "\n\nDo you want to apply it? You can type | ||
| 2246 | y -- to apply the local variables list. | ||
| 2247 | n -- to ignore the local variables list. | ||
| 2248 | ! -- to apply the local variables list, and mark these values (*) as | ||
| 2249 | safe (in the future, they can be set automatically.)\n\n") | ||
| 2250 | (dolist (elt vars) | ||
| 2251 | (cond ((member elt unsafe-vars) | ||
| 2252 | (princ " * ")) | ||
| 2253 | ((member elt risky-vars) | ||
| 2254 | (princ " ** ")) | ||
| 2255 | (t | ||
| 2256 | (princ " "))) | ||
| 2257 | (princ (car elt)) | ||
| 2258 | (princ " : ") | ||
| 2259 | (princ (cdr elt)) | ||
| 2260 | (princ "\n"))) | ||
| 2261 | (message "Please type y, n, or !: ") | ||
| 2262 | (let ((inhibit-quit t) | ||
| 2263 | (cursor-in-echo-area t)) | ||
| 2264 | (while (or (not (numberp (setq char (read-event)))) | ||
| 2265 | (not (memq (downcase char) | ||
| 2266 | '(?! ?y ?n ?\s ?\C-g)))) | ||
| 2267 | (message "Please type y, n, or !: ")) | ||
| 2268 | (if (= char ?\C-g) | ||
| 2269 | (setq quit-flag nil))) | ||
| 2270 | (setq char (downcase char)) | ||
| 2271 | (when (and (= char ?!) unsafe-vars) | ||
| 2272 | (dolist (elt unsafe-vars) | ||
| 2273 | (push elt safe-local-variable-values)) | ||
| 2274 | (customize-save-variable | ||
| 2275 | 'safe-local-variable-values | ||
| 2276 | safe-local-variable-values)) | ||
| 2277 | (or (= char ?!) | ||
| 2278 | (= char ?\s) | ||
| 2279 | (= char ?y)))))) | ||
| 2238 | 2280 | ||
| 2239 | (defun hack-local-variables-prop-line (&optional mode-only) | 2281 | (defun hack-local-variables-prop-line (&optional mode-only) |
| 2240 | "Set local variables specified in the -*- line. | 2282 | "Return local variables specified in the -*- line. |
| 2241 | Ignore any specification for `mode:' and `coding:'; | 2283 | Ignore any specification for `mode:' and `coding:'; |
| 2242 | `set-auto-mode' should already have handled `mode:', | 2284 | `set-auto-mode' should already have handled `mode:', |
| 2243 | `set-auto-coding' should already have handled `coding:'. | 2285 | `set-auto-coding' should already have handled `coding:'. |
| 2244 | If MODE-ONLY is non-nil, all we do is check whether the major mode | 2286 | |
| 2245 | is specified, returning t if it is specified." | 2287 | If MODE-ONLY is non-nil, all we do is check whether the major |
| 2288 | mode is specified, returning t if it is specified. Otherwise, | ||
| 2289 | return an alist of elements (VAR . VAL), where VAR is a variable | ||
| 2290 | and VAL is the specified value." | ||
| 2246 | (save-excursion | 2291 | (save-excursion |
| 2247 | (goto-char (point-min)) | 2292 | (goto-char (point-min)) |
| 2248 | (let ((result nil) | 2293 | (let ((end (set-auto-mode-1)) |
| 2249 | (end (set-auto-mode-1)) | 2294 | result mode-specified) |
| 2250 | mode-specified | ||
| 2251 | (enable-local-variables | ||
| 2252 | (and local-enable-local-variables enable-local-variables))) | ||
| 2253 | ;; Parse the -*- line into the RESULT alist. | 2295 | ;; Parse the -*- line into the RESULT alist. |
| 2254 | ;; Also set MODE-SPECIFIED if we see a spec or `mode'. | 2296 | ;; Also set MODE-SPECIFIED if we see a spec or `mode'. |
| 2255 | (cond ((not end) | 2297 | (cond ((not end) |
| @@ -2279,128 +2321,162 @@ is specified, returning t if it is specified." | |||
| 2279 | ;; so we must do that here as well. | 2321 | ;; so we must do that here as well. |
| 2280 | ;; That is inconsistent, but we're stuck with it. | 2322 | ;; That is inconsistent, but we're stuck with it. |
| 2281 | ;; The same can be said for `coding' in set-auto-coding. | 2323 | ;; The same can be said for `coding' in set-auto-coding. |
| 2282 | (or (equal (downcase (symbol-name key)) "mode") | 2324 | (or (and (equal (downcase (symbol-name key)) "mode") |
| 2325 | (setq mode-specified t)) | ||
| 2283 | (equal (downcase (symbol-name key)) "coding") | 2326 | (equal (downcase (symbol-name key)) "coding") |
| 2284 | (setq result (cons (cons key val) result))) | 2327 | (condition-case nil |
| 2285 | (if (equal (downcase (symbol-name key)) "mode") | 2328 | (push (cons (if (eq key 'eval) |
| 2286 | (setq mode-specified t)) | 2329 | 'eval |
| 2287 | (skip-chars-forward " \t;"))) | 2330 | (indirect-variable key)) |
| 2288 | (setq result (nreverse result)))) | 2331 | val) result) |
| 2289 | 2332 | (error nil))) | |
| 2290 | (if mode-only mode-specified | 2333 | (skip-chars-forward " \t;"))))) |
| 2291 | (if (and result | 2334 | |
| 2292 | (or mode-only | 2335 | (if mode-only |
| 2293 | (hack-local-variables-confirm | 2336 | mode-specified |
| 2294 | "Set local variables as specified in -*- line of %s? " | 2337 | result)))) |
| 2295 | enable-local-variables))) | ||
| 2296 | (let ((enable-local-eval enable-local-eval)) | ||
| 2297 | (while result | ||
| 2298 | (hack-one-local-variable (car (car result)) (cdr (car result))) | ||
| 2299 | (setq result (cdr result))))) | ||
| 2300 | nil)))) | ||
| 2301 | 2338 | ||
| 2302 | (defvar hack-local-variables-hook nil | 2339 | (defvar hack-local-variables-hook nil |
| 2303 | "Normal hook run after processing a file's local variables specs. | 2340 | "Normal hook run after processing a file's local variables specs. |
| 2304 | Major modes can use this to examine user-specified local variables | 2341 | Major modes can use this to examine user-specified local variables |
| 2305 | in order to initialize other data structure based on them.") | 2342 | in order to initialize other data structure based on them.") |
| 2306 | 2343 | ||
| 2344 | (defcustom safe-local-variable-values nil | ||
| 2345 | "List variable-value pairs that are considered safe. | ||
| 2346 | Each element is a cons cell (VAR . VAL), where VAR is a variable | ||
| 2347 | symbol and VAL is a value that is considered safe." | ||
| 2348 | :group 'find-file | ||
| 2349 | :type 'alist) | ||
| 2350 | |||
| 2307 | (defun hack-local-variables (&optional mode-only) | 2351 | (defun hack-local-variables (&optional mode-only) |
| 2308 | "Parse and put into effect this buffer's local variables spec. | 2352 | "Parse and put into effect this buffer's local variables spec. |
| 2309 | If MODE-ONLY is non-nil, all we do is check whether the major mode | 2353 | If MODE-ONLY is non-nil, all we do is check whether the major mode |
| 2310 | is specified, returning t if it is specified." | 2354 | is specified, returning t if it is specified." |
| 2311 | (let ((mode-specified | 2355 | (let ((enable-local-variables |
| 2312 | ;; If MODE-ONLY is t, we check here for specifying the mode | 2356 | (and local-enable-local-variables enable-local-variables)) |
| 2313 | ;; in the -*- line. If MODE-ONLY is nil, we process | 2357 | result) |
| 2314 | ;; the -*- line here. | 2358 | (when (or mode-only enable-local-variables) |
| 2315 | (hack-local-variables-prop-line mode-only)) | 2359 | (setq result (hack-local-variables-prop-line mode-only)) |
| 2316 | (enable-local-variables | 2360 | ;; Look for "Local variables:" line in last page. |
| 2317 | (and local-enable-local-variables enable-local-variables))) | 2361 | (save-excursion |
| 2318 | ;; Look for "Local variables:" line in last page. | 2362 | (goto-char (point-max)) |
| 2319 | (save-excursion | 2363 | (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) |
| 2320 | (goto-char (point-max)) | 2364 | 'move) |
| 2321 | (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move) | 2365 | (when (let ((case-fold-search t)) |
| 2322 | (when (let ((case-fold-search t)) | 2366 | (search-forward "Local Variables:" nil t)) |
| 2323 | (and (search-forward "Local Variables:" nil t) | 2367 | (skip-chars-forward " \t") |
| 2324 | (or mode-only | 2368 | ;; suffix is what comes after "local variables:" in its line. |
| 2325 | (hack-local-variables-confirm | 2369 | ;; prefix is what comes before "local variables:" in its line. |
| 2326 | "Set local variables as specified at end of %s? " | 2370 | (let ((suffix |
| 2327 | enable-local-variables)))) | 2371 | (concat |
| 2328 | (skip-chars-forward " \t") | 2372 | (regexp-quote (buffer-substring (point) |
| 2329 | (let ((enable-local-eval enable-local-eval) | 2373 | (line-end-position))) |
| 2330 | ;; suffix is what comes after "local variables:" in its line. | 2374 | "$")) |
| 2331 | (suffix | 2375 | (prefix |
| 2332 | (concat | 2376 | (concat "^" (regexp-quote |
| 2333 | (regexp-quote (buffer-substring (point) (line-end-position))) | 2377 | (buffer-substring (line-beginning-position) |
| 2334 | "$")) | 2378 | (match-beginning 0))))) |
| 2335 | ;; prefix is what comes before "local variables:" in its line. | 2379 | beg) |
| 2336 | (prefix | 2380 | |
| 2337 | (concat "^" (regexp-quote | 2381 | (forward-line 1) |
| 2338 | (buffer-substring (line-beginning-position) | 2382 | (let ((startpos (point)) |
| 2339 | (match-beginning 0))))) | 2383 | endpos |
| 2340 | beg) | 2384 | (thisbuf (current-buffer))) |
| 2341 | 2385 | (save-excursion | |
| 2342 | (forward-line 1) | 2386 | (unless (let ((case-fold-search t)) |
| 2343 | (let ((startpos (point)) | 2387 | (re-search-forward |
| 2344 | endpos | 2388 | (concat prefix "[ \t]*End:[ \t]*" suffix) |
| 2345 | (thisbuf (current-buffer))) | 2389 | nil t)) |
| 2346 | (save-excursion | 2390 | (error "Local variables list is not properly terminated")) |
| 2347 | (unless (let ((case-fold-search t)) | 2391 | (beginning-of-line) |
| 2348 | (re-search-forward | 2392 | (setq endpos (point))) |
| 2349 | (concat prefix "[ \t]*End:[ \t]*" suffix) | 2393 | |
| 2350 | nil t)) | 2394 | (with-temp-buffer |
| 2351 | (error "Local variables list is not properly terminated")) | 2395 | (insert-buffer-substring thisbuf startpos endpos) |
| 2352 | (beginning-of-line) | 2396 | (goto-char (point-min)) |
| 2353 | (setq endpos (point))) | 2397 | (subst-char-in-region (point) (point-max) ?\^m ?\n) |
| 2354 | 2398 | (while (not (eobp)) | |
| 2355 | (with-temp-buffer | 2399 | ;; Discard the prefix. |
| 2356 | (insert-buffer-substring thisbuf startpos endpos) | 2400 | (if (looking-at prefix) |
| 2357 | (goto-char (point-min)) | 2401 | (delete-region (point) (match-end 0)) |
| 2358 | (subst-char-in-region (point) (point-max) ?\^m ?\n) | 2402 | (error "Local variables entry is missing the prefix")) |
| 2359 | (while (not (eobp)) | 2403 | (end-of-line) |
| 2360 | ;; Discard the prefix. | 2404 | ;; Discard the suffix. |
| 2361 | (if (looking-at prefix) | 2405 | (if (looking-back suffix) |
| 2362 | (delete-region (point) (match-end 0)) | 2406 | (delete-region (match-beginning 0) (point)) |
| 2363 | (error "Local variables entry is missing the prefix")) | 2407 | (error "Local variables entry is missing the suffix")) |
| 2364 | (end-of-line) | 2408 | (forward-line 1)) |
| 2365 | ;; Discard the suffix. | 2409 | (goto-char (point-min)) |
| 2366 | (if (looking-back suffix) | 2410 | |
| 2367 | (delete-region (match-beginning 0) (point)) | 2411 | (while (not (eobp)) |
| 2368 | (error "Local variables entry is missing the suffix")) | 2412 | ;; Find the variable name; strip whitespace. |
| 2369 | (forward-line 1)) | 2413 | (skip-chars-forward " \t") |
| 2370 | (goto-char (point-min)) | 2414 | (setq beg (point)) |
| 2371 | 2415 | (skip-chars-forward "^:\n") | |
| 2372 | (while (not (eobp)) | 2416 | (if (eolp) (error "Missing colon in local variables entry")) |
| 2373 | ;; Find the variable name; strip whitespace. | 2417 | (skip-chars-backward " \t") |
| 2374 | (skip-chars-forward " \t") | 2418 | (let* ((str (buffer-substring beg (point))) |
| 2375 | (setq beg (point)) | 2419 | (var (read str)) |
| 2376 | (skip-chars-forward "^:\n") | 2420 | val) |
| 2377 | (if (eolp) (error "Missing colon in local variables entry")) | 2421 | ;; Read the variable value. |
| 2378 | (skip-chars-backward " \t") | 2422 | (skip-chars-forward "^:") |
| 2379 | (let* ((str (buffer-substring beg (point))) | 2423 | (forward-char 1) |
| 2380 | (var (read str)) | 2424 | (setq val (read (current-buffer))) |
| 2381 | val) | 2425 | (if mode-only |
| 2382 | ;; Read the variable value. | 2426 | (if (eq var 'mode) |
| 2383 | (skip-chars-forward "^:") | 2427 | (setq result t)) |
| 2384 | (forward-char 1) | 2428 | (unless (eq var 'coding) |
| 2385 | (setq val (read (current-buffer))) | 2429 | (condition-case nil |
| 2386 | (if mode-only | 2430 | (push (cons (if (eq var 'eval) |
| 2387 | (if (eq var 'mode) | 2431 | 'eval |
| 2388 | (setq mode-specified t)) | 2432 | (indirect-variable var)) |
| 2389 | ;; Set the variable. "Variables" mode and eval are funny. | 2433 | val) result) |
| 2390 | (with-current-buffer thisbuf | 2434 | (error nil))))) |
| 2391 | (hack-one-local-variable var val)))) | 2435 | (forward-line 1))))))) |
| 2392 | (forward-line 1))))))) | 2436 | |
| 2393 | (unless mode-only | 2437 | ;; We've read all the local variables. Now, return whether the |
| 2394 | (run-hooks 'hack-local-variables-hook)) | 2438 | ;; mode is specified (if MODE-ONLY is non-nil), or set the |
| 2395 | mode-specified)) | 2439 | ;; variables (if MODE-ONLY is nil.) |
| 2396 | 2440 | (if mode-only | |
| 2397 | (defvar ignored-local-variables () | 2441 | result |
| 2442 | (setq result (nreverse result)) | ||
| 2443 | (dolist (ignored ignored-local-variables) | ||
| 2444 | (setq result (assq-delete-all ignored result))) | ||
| 2445 | (if (null enable-local-eval) | ||
| 2446 | (setq result (assq-delete-all 'eval result))) | ||
| 2447 | ;; Find those variables that we may want to save to | ||
| 2448 | ;; `safe-local-variable-values'. | ||
| 2449 | (let (risky-vars unsafe-vars) | ||
| 2450 | (dolist (elt result) | ||
| 2451 | (let ((var (car elt)) | ||
| 2452 | (val (cdr elt))) | ||
| 2453 | (or (eq var 'mode) | ||
| 2454 | (and (eq var 'eval) | ||
| 2455 | (or (eq enable-local-eval t) | ||
| 2456 | (hack-one-local-variable-eval-safep | ||
| 2457 | (eval (quote val))))) | ||
| 2458 | (safe-local-variable-p var val) | ||
| 2459 | (and (risky-local-variable-p var val) | ||
| 2460 | (push elt risky-vars)) | ||
| 2461 | (push elt unsafe-vars)))) | ||
| 2462 | (if (or (and (eq enable-local-variables t) | ||
| 2463 | (null unsafe-vars) | ||
| 2464 | (null risky-vars)) | ||
| 2465 | (hack-local-variables-confirm | ||
| 2466 | result unsafe-vars risky-vars)) | ||
| 2467 | (dolist (elt result) | ||
| 2468 | (hack-one-local-variable (car elt) (cdr elt))))) | ||
| 2469 | (run-hooks 'hack-local-variables-hook))))) | ||
| 2470 | |||
| 2471 | (defvar ignored-local-variables | ||
| 2472 | '(ignored-local-variables safe-local-variable-values) | ||
| 2398 | "Variables to be ignored in a file's local variable spec.") | 2473 | "Variables to be ignored in a file's local variable spec.") |
| 2399 | 2474 | ||
| 2400 | ;; Get confirmation before setting these variables as locals in a file. | 2475 | ;; Get confirmation before setting these variables as locals in a file. |
| 2401 | (put 'debugger 'risky-local-variable t) | 2476 | (put 'debugger 'risky-local-variable t) |
| 2402 | (put 'enable-local-eval 'risky-local-variable t) | 2477 | (put 'enable-local-eval 'risky-local-variable t) |
| 2403 | (put 'ignored-local-variables 'risky-local-variable t) | 2478 | (put 'ignored-local-variables 'risky-local-variable t) |
| 2479 | (put 'ignored-local-variables 'safe-local-variable-values t) | ||
| 2404 | (put 'eval 'risky-local-variable t) | 2480 | (put 'eval 'risky-local-variable t) |
| 2405 | (put 'file-name-handler-alist 'risky-local-variable t) | 2481 | (put 'file-name-handler-alist 'risky-local-variable t) |
| 2406 | (put 'inhibit-quit 'risky-local-variable t) | 2482 | (put 'inhibit-quit 'risky-local-variable t) |
| @@ -2452,27 +2528,68 @@ is specified, returning t if it is specified." | |||
| 2452 | (put 'display-time-string 'risky-local-variable t) | 2528 | (put 'display-time-string 'risky-local-variable t) |
| 2453 | (put 'parse-time-rules 'risky-local-variable t) | 2529 | (put 'parse-time-rules 'risky-local-variable t) |
| 2454 | 2530 | ||
| 2455 | ;; This case is safe because the user gets to check it before it is used. | 2531 | ;; Commonly-encountered local variables that are safe: |
| 2456 | (put 'compile-command 'safe-local-variable 'stringp) | 2532 | (let ((string-or-null (lambda (a) (or (stringp a) (null a))))) |
| 2457 | 2533 | (eval | |
| 2458 | (defun risky-local-variable-p (sym &optional val) | 2534 | `(mapc (lambda (pair) |
| 2459 | "Non-nil if SYM could be dangerous as a file-local variable with value VAL. | 2535 | (put (car pair) 'safe-local-variable (cdr pair))) |
| 2460 | If VAL is nil or omitted, the question is whether any value might be | 2536 | '((byte-compile-dynamic . t) |
| 2461 | dangerous." | 2537 | (c-basic-offset . integerp) |
| 2538 | (c-file-style . stringp) | ||
| 2539 | (c-indent-level . integerp) | ||
| 2540 | (comment-column . integerp) | ||
| 2541 | (compile-command . ,string-or-null) | ||
| 2542 | (fill-column . integerp) | ||
| 2543 | (fill-prefix . ,string-or-null) | ||
| 2544 | (indent-tabs-mode . t) | ||
| 2545 | (kept-new-versions . integerp) | ||
| 2546 | (no-byte-compile . t) | ||
| 2547 | (no-update-autoloads . t) | ||
| 2548 | (outline-regexp . ,string-or-null) | ||
| 2549 | (page-delimiter . ,string-or-null) | ||
| 2550 | (paragraph-start . ,string-or-null) | ||
| 2551 | (paragraph-separate . ,string-or-null) | ||
| 2552 | (sentence-end . ,string-or-null) | ||
| 2553 | (sentence-end-double-space . t) | ||
| 2554 | (tab-width . integerp) | ||
| 2555 | (version-control . t))))) | ||
| 2556 | |||
| 2557 | (defun safe-local-variable-p (sym val) | ||
| 2558 | "Non-nil if SYM is safe as a file-local variable with value VAL. | ||
| 2559 | It is safe if any of these conditions are met: | ||
| 2560 | |||
| 2561 | * There is a matching entry (SYM . VAL) in the | ||
| 2562 | `safe-local-variable-values' user option. | ||
| 2563 | |||
| 2564 | * The `safe-local-variable' property of SYM is t. | ||
| 2565 | |||
| 2566 | * The `safe-local-variable' property of SYM is a function that | ||
| 2567 | evaluates to a non-nil value with VAL as an argument." | ||
| 2568 | (or (member (cons sym val) safe-local-variable-values) | ||
| 2569 | (let ((safep (get sym 'safe-local-variable))) | ||
| 2570 | (or (eq safep t) | ||
| 2571 | (and (functionp safep) | ||
| 2572 | (funcall safep val)))))) | ||
| 2573 | |||
| 2574 | (defun risky-local-variable-p (sym &optional ignored) | ||
| 2575 | "Non-nil if SYM could be dangerous as a file-local variable. | ||
| 2576 | It is dangerous if either of these conditions are met: | ||
| 2577 | |||
| 2578 | * Its `risky-local-variable' property is non-nil. | ||
| 2579 | |||
| 2580 | * Its name ends with \"hook(s)\", \"function(s)\", \"form(s)\", \"map\", | ||
| 2581 | \"program\", \"command(s)\", \"predicate(s)\", \"frame-alist\", | ||
| 2582 | \"mode-alist\", \"font-lock-(syntactic-)keyword*\", or | ||
| 2583 | \"map-alist\"." | ||
| 2462 | ;; If this is an alias, check the base name. | 2584 | ;; If this is an alias, check the base name. |
| 2463 | (condition-case nil | 2585 | (condition-case nil |
| 2464 | (setq sym (indirect-variable sym)) | 2586 | (setq sym (indirect-variable sym)) |
| 2465 | (error nil)) | 2587 | (error nil)) |
| 2466 | (let ((safep (get sym 'safe-local-variable))) | 2588 | (or (get sym 'risky-local-variable) |
| 2467 | (or (get sym 'risky-local-variable) | 2589 | (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|\ |
| 2468 | (and (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-commands?$\\|-predicates?$\\|font-lock-keywords$\\|font-lock-keywords-[0-9]+$\\|font-lock-syntactic-keywords$\\|-frame-alist$\\|-mode-alist$\\|-map$\\|-map-alist$" | 2590 | -commands?$\\|-predicates?$\\|font-lock-keywords$\\|font-lock-keywords\ |
| 2469 | (symbol-name sym)) | 2591 | -[0-9]+$\\|font-lock-syntactic-keywords$\\|-frame-alist$\\|-mode-alist$\\|\ |
| 2470 | (not safep)) | 2592 | -map$\\|-map-alist$" (symbol-name sym)))) |
| 2471 | ;; If the safe-local-variable property isn't t or nil, | ||
| 2472 | ;; then it must return non-nil on the proposed value to be safe. | ||
| 2473 | (and (not (memq safep '(t nil))) | ||
| 2474 | (or (null val) | ||
| 2475 | (not (funcall safep val))))))) | ||
| 2476 | 2593 | ||
| 2477 | (defcustom safe-local-eval-forms nil | 2594 | (defcustom safe-local-eval-forms nil |
| 2478 | "*Expressions that are considered \"safe\" in an `eval:' local variable. | 2595 | "*Expressions that are considered \"safe\" in an `eval:' local variable. |
| @@ -2529,35 +2646,12 @@ asking you for confirmation." | |||
| 2529 | ok))))))) | 2646 | ok))))))) |
| 2530 | 2647 | ||
| 2531 | (defun hack-one-local-variable (var val) | 2648 | (defun hack-one-local-variable (var val) |
| 2532 | "\"Set\" one variable in a local variables spec. | 2649 | "Set local variable VAR with value VAL." |
| 2533 | A few patterns are specified so that any name which matches one | ||
| 2534 | is considered risky." | ||
| 2535 | (cond ((eq var 'mode) | 2650 | (cond ((eq var 'mode) |
| 2536 | (funcall (intern (concat (downcase (symbol-name val)) | 2651 | (funcall (intern (concat (downcase (symbol-name val)) |
| 2537 | "-mode")))) | 2652 | "-mode")))) |
| 2538 | ((eq var 'coding) | 2653 | ((eq var 'eval) |
| 2539 | ;; We have already handled coding: tag in set-auto-coding. | 2654 | (save-excursion (eval val))) |
| 2540 | nil) | ||
| 2541 | ((memq var ignored-local-variables) | ||
| 2542 | nil) | ||
| 2543 | ;; "Setting" eval means either eval it or do nothing. | ||
| 2544 | ;; Likewise for setting hook variables. | ||
| 2545 | ((risky-local-variable-p var val) | ||
| 2546 | ;; Permit evalling a put of a harmless property. | ||
| 2547 | ;; if the args do nothing tricky. | ||
| 2548 | (if (or (and (eq var 'eval) | ||
| 2549 | (hack-one-local-variable-eval-safep val)) | ||
| 2550 | ;; Permit eval if not root and user says ok. | ||
| 2551 | (and (not (zerop (user-uid))) | ||
| 2552 | (hack-local-variables-confirm | ||
| 2553 | "Process `eval' or hook local variables in %s? " | ||
| 2554 | enable-local-eval))) | ||
| 2555 | (if (eq var 'eval) | ||
| 2556 | (save-excursion (eval val)) | ||
| 2557 | (make-local-variable var) | ||
| 2558 | (set var val)) | ||
| 2559 | (message "Ignoring risky spec in the local variables list"))) | ||
| 2560 | ;; Ordinary variable, really set it. | ||
| 2561 | (t (make-local-variable var) | 2655 | (t (make-local-variable var) |
| 2562 | ;; Make sure the string has no text properties. | 2656 | ;; Make sure the string has no text properties. |
| 2563 | ;; Some text properties can get evaluated in various ways, | 2657 | ;; Some text properties can get evaluated in various ways, |
diff --git a/lisp/find-lisp.el b/lisp/find-lisp.el index c7527fe21f5..5cedaa60e35 100644 --- a/lisp/find-lisp.el +++ b/lisp/find-lisp.el | |||
| @@ -359,9 +359,5 @@ It is a function which takes two arguments, the directory and its parent." | |||
| 359 | 359 | ||
| 360 | (provide 'find-lisp) | 360 | (provide 'find-lisp) |
| 361 | 361 | ||
| 362 | ;; Local Variables: | ||
| 363 | ;; autocompile: t | ||
| 364 | ;; End: | ||
| 365 | |||
| 366 | ;;; arch-tag: a711374c-f12a-46f6-aa18-ba7d77b9602a | 362 | ;;; arch-tag: a711374c-f12a-46f6-aa18-ba7d77b9602a |
| 367 | ;;; find-lisp.el ends here | 363 | ;;; find-lisp.el ends here |
diff --git a/lisp/icomplete.el b/lisp/icomplete.el index f835d91ff9a..191f1d324e6 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el | |||
| @@ -325,7 +325,7 @@ are exhibited within the square braces.)" | |||
| 325 | 325 | ||
| 326 | ;;;_* Local emacs vars. | 326 | ;;;_* Local emacs vars. |
| 327 | ;;;Local variables: | 327 | ;;;Local variables: |
| 328 | ;;;outline-layout: (-2 :) | 328 | ;;;allout-layout: (-2 :) |
| 329 | ;;;End: | 329 | ;;;End: |
| 330 | 330 | ||
| 331 | ;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f | 331 | ;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f |
diff --git a/lisp/play/landmark.el b/lisp/play/landmark.el index ed4181e5b8d..63d7a9fe33a 100644 --- a/lisp/play/landmark.el +++ b/lisp/play/landmark.el | |||
| @@ -1694,13 +1694,13 @@ Use \\[describe-mode] for more info." | |||
| 1694 | 1694 | ||
| 1695 | ;;;_ + Local variables | 1695 | ;;;_ + Local variables |
| 1696 | 1696 | ||
| 1697 | ;;; The following `outline-layout' local variable setting: | 1697 | ;;; The following `allout-layout' local variable setting: |
| 1698 | ;;; - closes all topics from the first topic to just before the third-to-last, | 1698 | ;;; - closes all topics from the first topic to just before the third-to-last, |
| 1699 | ;;; - shows the children of the third to last (config vars) | 1699 | ;;; - shows the children of the third to last (config vars) |
| 1700 | ;;; - and the second to last (code section), | 1700 | ;;; - and the second to last (code section), |
| 1701 | ;;; - and closes the last topic (this local-variables section). | 1701 | ;;; - and closes the last topic (this local-variables section). |
| 1702 | ;;;Local variables: | 1702 | ;;;Local variables: |
| 1703 | ;;;outline-layout: (0 : -1 -1 0) | 1703 | ;;;allout-layout: (0 : -1 -1 0) |
| 1704 | ;;;End: | 1704 | ;;;End: |
| 1705 | 1705 | ||
| 1706 | (provide 'landmark) | 1706 | (provide 'landmark) |