unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3)
@ 2006-06-20 11:13 Kim F. Storm
  2006-06-20 12:36 ` [gmane.emacs.sources] dir-locals.el Chong Yidong
  2006-06-20 22:18 ` [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3) Richard Stallman
  0 siblings, 2 replies; 6+ messages in thread
From: Kim F. Storm @ 2006-06-20 11:13 UTC (permalink / raw)
  Cc: Dave Love


Dave Love has written a clean alternative to the "dirvars" package
posted recently, but recent (major) changes to hack-local-variables
broke his code.

Before, hack-local-variables-hook was run unconditionally at the end
of hack-local-variables, but now it is only run if the file has local
variables.

Is that change intentional or just an oversight?



Here is Dave's code:

;;; dir-locals.el --- Local variables for a directory tree

;; Copyright (C) 2005, 2006  Free Software Foundation, Inc.

;; Author: Dave Love <fx@gnu.org>
;; Keywords: files
;; $Revision: 1.6 $
;; URL: http://www.loveshack.ukfsn.org/emacs

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; It can be useful to specify local variables directory-wide, e.g. to
;; define CC mode styles consistently.  This library implements such a
;; scheme, controlled by the global minor mode `dir-locals-mode'.

;; Place a file named `.emacs-locals' (or the value of
;; `dir-locals-file-name') in the directory root.  This should specify
;; local variables in the usual way.  The values it sets are inherited
;; when a file in the directory tree is found.  Local variables
;; specified in the found file override the directory-wide ones.

;; However, `eval' pseudo-variables specified in the file are
;; evaluated (assuming `enable-local-eval' is true) _before_ any
;; directory-wide processing, and they are evaluated in a scratch
;; buffer, so that they are only useful for side effects on local
;; variables.  `mode' pseudo-variables which specify minor modes
;; toggle those modes for files within the directory.  If
;; .emacs-locals specifies a major mode, it doesn't propagate, but any
;; local variables and minor modes its hook sets will; thus it should
;; normally not specify a major mode.  The `coding' pseudo-variable
;; will not propagate from .emacs-locals.

;; For example, with dir-locals mode on, placing this in .emacs-locals
;; at the top-level of the Linux source tree would set the C
;; indentation style appropriately for files within the tree:
;;
;;   Local variables:
;;   c-file-style: "linux"
;;   End:
;;
;; (and ignore the stupid remarks in Documentation/CodingStyle).

;; Another possible use is, say, setting change-log parameters in
;; different trees for which the Emacs 22 development source broke use
;; of change-log-mode-hook.

;; NB: this no longer works properly with the Emacs 22 codebase since
;; that changed the way hack-local-variables-hook is run; sigh.  In
;; that case it falls back to using `find-file-hook', which doesn't
;; really do the right thing, but should mostly work OK.

;; Another, less clean, implementation of this sort of thing was
;; posted to gnu-emacs-sources as dirvals.el by Benjamin Rutt
;; <rutt.4@osu.edu>, June 2006, based on work by Matt Armstrong
;; <matt@lickey.com>.  It uses a different format for the equivalent
;; of .emacs-locals.

;;; Code:

(defgroup dir-locals ()
  "Directory-wide file-local variables"
  :link '(emacs-commentary-link "dir-locals")
  :group 'files)

(defcustom dir-locals-file-name ".emacs-locals"
  "File name used by Dir-Locals mode to specify local variables.
This should specify local variables in the normal way.  When Dir-Locals
minor mode is active, these will be inherited by files found in a
directory tree containing such a file at its root.

This may also be a function of no arguments which returns the name to
use, allowing arbitrary per-directory customization of the
per-directory customization file on the basis of `default-directory'."
  :group 'dir-locals
  :type '(choice file function))

;; Adapted from dirvals.el.
(defcustom dir-locals-chase-remote nil
  "Non-nil means search upwards for `dir-locals-file-name' in remote filesystem."
  :group 'dir-locals
  :type 'boolean)

(define-minor-mode dir-locals-mode
  "Toggle use of directory-wide file-local variables.
See `dir-locals-file-name'."
  :global t
  ;; Emacs 22 doesn't run `hack-local-variables-hook' if the file has
  ;; no local variables; sigh.  Using this new hook at least doesn't
  ;; catch the case of just changing the major mode, but mostly works.
  (if (boundp 'find-file-hook)
      (if dir-locals-mode
	  (add-hook 'find-file-hook 'dir-locals-hack-local-variables)
	(remove-hook 'find-file-hook 'dir-locals-hack-local-variables))
    (if dir-locals-mode
	(add-hook 'hack-local-variables-hook 'dir-locals-hack-local-variables)
      (remove-hook 'hack-local-variables-hook
		   'dir-locals-hack-local-variables))))

;; Following find-change-log.  Fixme:  Should be abstracted from there.
(defun dir-locals-tree-find (file)
  "Find FILE in the current directory or one of its parents.
If one is found, return its fully-qualified name, otherwise return
nil.

FILE may be a string or a nullary function returning one on the basis
of `default-directory'."
  (unless (and (not dir-locals-chase-remote)
	       (fboundp 'file-remote-p)	; not in Emacs 21
	       (file-remote-p default-directory))
    (let* ((dir-name
	    ;; Chase links in the source file and start searching in
	    ;; the dir where it resides.
	    (or (if buffer-file-name
		    (file-name-directory (file-chase-links buffer-file-name)))
		default-directory))
	   (file (if (functionp file)
		     (funcall file)
		   file))
	   (file1 (if (file-directory-p dir-name)
		      (expand-file-name file dir-name))))
      ;; Chase links before visiting the file.  This makes it easier
      ;; to use a file for several related directories.
      (setq file1 (expand-file-name (file-chase-links file1)))
      ;; Move up in the dir hierarchy till we find a suitable file.
      (while (and (not (file-exists-p file1))
		  (setq dir-name (file-name-directory
				  (directory-file-name
				   (file-name-directory file1))))
		  ;; Give up if we are already at the root dir.
		  (not (string= (file-name-directory file1) dir-name)))
	;; Move up to the parent dir and try again.
	(setq file1 (expand-file-name (file-name-nondirectory file) dir-name)))
      (if (file-exists-p file1)
	  file1))))

(defun dir-locals-hack-local-variables ()
  "Set local variables from directory-wide values.
Inherit the local variables set in `dir-locals-file-name' if that is
found by `dir-locals-tree-find'.  Ignore everything ignored by
`hack-local-variables'."
  (let* ((file (dir-locals-tree-find dir-locals-file-name))
	 (hack-local-variables-hook nil)
	 (buffer-file
	  (if buffer-file-name
	      (expand-file-name (file-chase-links buffer-file-name))))
	 ;; Fixme:  Probably condition-case this and ensure any error
	 ;; messages indicate the directory file.
	 (vars (when (and file
			  ;; Don't do it twice, so as to avoid
			  ;; repeating possible interactive queries.
			  (not (equal file buffer-file)))
		 (with-temp-buffer
		   ;; Make queries from `hack-local-variables' clearer.
		   (rename-buffer (file-name-nondirectory file) t)
		   (insert-file-contents file)
		   (let* ((locals (buffer-local-variables))
			  (_ (hack-local-variables))
			 (new-locals (buffer-local-variables)))
		     ;; Derive the list of new pairs.
		     (dolist (l locals)
		       (setq new-locals (delete l new-locals)))
		     ;; And some internals which get updated.
		     (dolist (l '(buffer-display-time buffer-display-count))
		       (setq new-locals (assq-delete-all l new-locals)))
		     new-locals)))))
    (dolist (v vars)
      (let ((sym (car v)))
	(unless (local-variable-p sym)	; file-locals take precedence
	  (if (and (string-match "-mode\\'" (symbol-name sym))
		   (fboundp sym))
	      (funcall sym)
	    (set (make-local-variable sym) (cdr v))))))))

(provide 'dir-locals)

;;; dir-locals.el ends here

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gmane.emacs.sources] dir-locals.el
  2006-06-20 11:13 [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3) Kim F. Storm
@ 2006-06-20 12:36 ` Chong Yidong
  2006-06-20 22:23   ` Chong Yidong
  2006-06-20 22:18 ` [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3) Richard Stallman
  1 sibling, 1 reply; 6+ messages in thread
From: Chong Yidong @ 2006-06-20 12:36 UTC (permalink / raw)
  Cc: Dave Love, emacs-devel

storm@cua.dk (Kim F. Storm) writes:

> Before, hack-local-variables-hook was run unconditionally at the end
> of hack-local-variables, but now it is only run if the file has local
> variables.
>
> Is that change intentional or just an oversight?

It is an oversight.  This little patch should fix it; I'll install it
over the next few days.

*** emacs/lisp/files.el.~1.844.~	2006-06-12 23:38:23.000000000 -0400
--- emacs/lisp/files.el	2006-06-20 08:34:27.000000000 -0400
***************
*** 2635,2642 ****
  		      (hack-local-variables-confirm
  		       result unsafe-vars risky-vars))
  		  (dolist (elt result)
! 		    (hack-one-local-variable (car elt) (cdr elt))))))
! 	  (run-hooks 'hack-local-variables-hook))))))
  
  (defun safe-local-variable-p (sym val)
    "Non-nil if SYM is safe as a file-local variable with value VAL.
--- 2635,2642 ----
  		      (hack-local-variables-confirm
  		       result unsafe-vars risky-vars))
  		  (dolist (elt result)
! 		    (hack-one-local-variable (car elt) (cdr elt)))))))
! 	(run-hooks 'hack-local-variables-hook)))))
  
  (defun safe-local-variable-p (sym val)
    "Non-nil if SYM is safe as a file-local variable with value VAL.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3)
  2006-06-20 11:13 [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3) Kim F. Storm
  2006-06-20 12:36 ` [gmane.emacs.sources] dir-locals.el Chong Yidong
@ 2006-06-20 22:18 ` Richard Stallman
  1 sibling, 0 replies; 6+ messages in thread
From: Richard Stallman @ 2006-06-20 22:18 UTC (permalink / raw)
  Cc: fx, emacs-devel

    Before, hack-local-variables-hook was run unconditionally at the end
    of hack-local-variables, but now it is only run if the file has local
    variables.

    Is that change intentional or just an oversight?

It was probably unintentional, since the doc string was not changed
accordingly.  I see no reason not to change it back.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gmane.emacs.sources] dir-locals.el
  2006-06-20 12:36 ` [gmane.emacs.sources] dir-locals.el Chong Yidong
@ 2006-06-20 22:23   ` Chong Yidong
  2006-08-02  8:39     ` Masatake YAMATO
  0 siblings, 1 reply; 6+ messages in thread
From: Chong Yidong @ 2006-06-20 22:23 UTC (permalink / raw)
  Cc: Dave Love, emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> storm@cua.dk (Kim F. Storm) writes:
>
>> Before, hack-local-variables-hook was run unconditionally at the end
>> of hack-local-variables, but now it is only run if the file has local
>> variables.
>>
>> Is that change intentional or just an oversight?
>
> It is an oversight.  This little patch should fix it; I'll install it
> over the next few days.

I checked it in.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gmane.emacs.sources] dir-locals.el
  2006-06-20 22:23   ` Chong Yidong
@ 2006-08-02  8:39     ` Masatake YAMATO
  2006-08-02 21:20       ` Richard Stallman
  0 siblings, 1 reply; 6+ messages in thread
From: Masatake YAMATO @ 2006-08-02  8:39 UTC (permalink / raw)
  Cc: cyd, fx, storm

Is there any progress about merging dir-locals.el into emacs?
Is there any issue for merging? If yes, I'll work on.

Masatake

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gmane.emacs.sources] dir-locals.el
  2006-08-02  8:39     ` Masatake YAMATO
@ 2006-08-02 21:20       ` Richard Stallman
  0 siblings, 0 replies; 6+ messages in thread
From: Richard Stallman @ 2006-08-02 21:20 UTC (permalink / raw)
  Cc: cyd, storm, fx, emacs-devel

    Is there any progress about merging dir-locals.el into emacs?

Sorry, I don't recall where this stands.

We should not merge it now, though.
It should wait for after the release.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-08-02 21:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-20 11:13 [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3) Kim F. Storm
2006-06-20 12:36 ` [gmane.emacs.sources] dir-locals.el Chong Yidong
2006-06-20 22:23   ` Chong Yidong
2006-08-02  8:39     ` Masatake YAMATO
2006-08-02 21:20       ` Richard Stallman
2006-06-20 22:18 ` [gmane.emacs.sources] dir-locals.el (was: dirvars.el 1.3) Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).