* bug#18721: 25.0.50; choose major mode from .dir-locals.el
@ 2014-10-14 20:06 Tom Tromey
2014-10-14 23:54 ` Stefan Monnier
2017-01-15 2:38 ` bug#18721: patch Tom Tromey
0 siblings, 2 replies; 10+ messages in thread
From: Tom Tromey @ 2014-10-14 20:06 UTC (permalink / raw)
To: 18721
It would be nice if there were a way to associate
file extensions with major modes in .dir-locals.el.
This would let projects use project-specific extensions
without requiring per-file mode cookies or having
everybody modify their .emacs
In GNU Emacs 25.0.50.3 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.9)
of 2014-10-09 on pokyo
Repository revision: 118080 eggert@cs.ucla.edu-20141009065410-dhgjku4gclzl71kj
Windowing system distributor `Fedora Project', version 11.0.11404000
System Description: Fedora release 20 (Heisenbug)
Configured using:
`configure --prefix=/home/tromey/Emacs/install'
Configured features:
XPM JPEG TIFF GIF PNG SOUND GPM DBUS GSETTINGS NOTIFY ACL LIBSELINUX
GNUTLS LIBXML2 FREETYPE LIBOTF XFT ZLIB
Important settings:
value of $LANG: en_US.UTF-8
locale-coding-system: utf-8-unix
Major mode: C++/l
Minor modes in effect:
shell-dirtrack-mode: t
erc-spelling-mode: t
erc-truncate-mode: t
diff-auto-refine-mode: t
bug-reference-prog-mode: t
flyspell-mode: t
which-function-mode: t
projectile-global-mode: t
projectile-mode: t
global-auto-revert-mode: t
desktop-save-mode: t
erc-status-mode: t
erc-services-mode: t
erc-list-mode: t
erc-menu-mode: t
erc-autojoin-mode: t
erc-ring-mode: t
erc-networks-mode: t
erc-pcomplete-mode: t
erc-track-mode: t
erc-track-minor-mode: t
erc-match-mode: t
erc-button-mode: t
erc-fill-mode: t
erc-stamp-mode: t
erc-netsplit-mode: t
erc-irccontrols-mode: t
erc-noncommands-mode: t
erc-move-to-prompt-mode: t
erc-readonly-mode: t
savehist-mode: t
tooltip-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
column-number-mode: t
line-number-mode: t
auto-fill-function: tromey-c++-do-auto-fill
abbrev-mode: t
Recent input:
n e n o SPC 1 3 RET SPC 3 0 : SPC SPC SPC 1 3 SPC SPC
SPC SPC 9 5 SPC [ SPC SPC SPC 0 ] SPC c o l s p a n
SPC 1 RET SPC 3 2 : SPC SPC SPC 1 3 SPC SPC SPC 1 0
8 SPC [ SPC SPC 1 3 ] SPC x d e l t a SPC SPC RET SPC
3 3 : SPC SPC SPC 1 3 SPC SPC SPC 1 0 8 SPC [ SPC SPC
SPC 0 ] SPC c o l s p a n SPC 8 RET RET E x c e p t
i o n SPC t a b l e : RET k i n d SPC SPC SPC SPC SPC
SPC s t a c k SPC SPC SPC SPC s t a r t SPC SPC SPC
SPC SPC SPC e n d RET SPC c a t c h SPC SPC SPC SPC
SPC SPC SPC SPC 0 SPC SPC SPC SPC SPC SPC SPC 1 4 SPC
SPC SPC SPC SPC SPC SPC 4 3 RET SPC f i n a l l y SPC
SPC SPC SPC SPC SPC 0 SPC SPC SPC SPC SPC SPC SPC 1
4 SPC SPC SPC SPC SPC SPC SPC 7 9 ESC [ 2 0 1 ~ RET
C-a C-k C-x C-x C-g C-u C-@ C-x C-s <switch-frame>
C-z n C-z n <f10> <f10> C-z n C-z n <f10> <f10> <switch-frame>
<switch-frame> C-z n C-z n <f10> <f10> <f10> <switch-frame>
<switch-frame> C-x C-c <switch-frame> C-z n M-x r e
o p r <M-backspace> r e p r <backspace> <backspace>
p o e r <backspace> r <backspace> t <backspace> <backspace>
r t - e m <tab> <return>
Recent messages:
C-z C-z is undefined
Quit
(New file)
When done with a buffer, type C-x #
Mark set
Auto-saving...
Quit
Saving file /tmp/L...
Wrote /tmp/L
(No files need saving)
Load-path shadows:
/home/tromey/.emacs.d/elpa/css-mode-1.0/css-mode hides /home/tromey/Emacs/install/share/emacs/25.0.50/lisp/textmodes/css-mode
/home/tromey/.emacs.d/elpa/bubbles-0.5/bubbles hides /home/tromey/Emacs/install/share/emacs/25.0.50/lisp/play/bubbles
/home/tromey/Emacs/install/share/emacs/25.0.50/lisp/loaddefs hides /home/tromey/Emacs/install/share/emacs/25.0.50/lisp/obsolete/loaddefs
Features:
(shadow emacsbug nxml-uchnm rng-xsd xsd-regexp rng-cmpct rng-nxml
rng-valid rng-loc rng-uri rng-parse nxml-parse rng-match rng-dt rng-util
rng-pttrn nxml-ns nxml-mode nxml-outln nxml-rap nxml-util nxml-glyph
nxml-enc xmltok vc-annotate ido log-edit eww log-view pcvs-util novice
etags find-dired ffap two-column autoconf autoconf-mode sh-script smie
executable shell find-file eieio-opt speedbar sb-image ezimage dframe
help-mode gdb-shell webjump dabbrev copyright idutils derived gnus-fun
flow-fill gnus-html xml mm-url mailalias bbdb-sc supercite regi
mail-hist nnir shr-color color xterm url-http url-gw url-auth url-queue
url-cache url url-proxy url-privacy url-expand url-methods url-history
url-cookie url-domsuf url-util url-parse url-vars shr browse-url
misearch multi-isearch erc-spelling erc-truncate bbdb-gui bbdb-hooks
mule-util sort smiley gnus-cite mm-archive gnus-async gnus-bcklg qp
gnus-ml disp-table gnus-topic nndraft nnmh nnfolder utf-7 bbdb-gnus
bbdb-snarf mail-extr bbdb-com warnings cl gv gnutls network-stream
starttls gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-msg
nntp gnus-cache gnus-registry registry eieio-base gnus-art mm-uu mml2015
mm-view mml-smime smime dig mailcap gnus-sum gnus-group gnus-undo
smtpmail sendmail gnus-start gnus-cloud nnimap nnmail mail-source tls
utf7 netrc nnoo parse-time gnus-spec gnus-int gnus-range gnus-win gnus
gnus-ems nnheader message rfc822 mml mml-sec mm-decode mm-bodies
mm-encode mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mailabbrev
mail-utils gmm-utils mailheader goto-addr add-log dired-aux gud
org-element org-rmail org-mhe org-irc org-info org-gnus org-docview
doc-view jka-compr image-mode dired org-bibtex bibtex org-bbdb org-w3m
org org-macro org-footnote org-pcomplete org-list org-faces org-entities
noutline outline org-version ob-emacs-lisp ob ob-tangle ob-ref ob-lob
ob-table ob-exp org-src ob-keys ob-comint ob-core ob-eval org-compat
org-macs org-loaddefs conf-mode python sgml-mode vc-arch vc-mtn vc-hg
vc-bzr vc-sccs vc-svn vc-cvs vc-rcs js json smerge-mode diff-mode
easy-mmode bug-reference vc-git cc-mode cc-fonts cc-guess cc-menus
cc-cmds flyspell ispell eldoc diminish appt diary-lib diary-loaddefs
cal-menu calendar cal-loaddefs which-func imenu projectile edmacro
kmacro pkg-info find-func lisp-mnt epl grep compile dash s minimap
autorevert filenotify desktop frameset cus-start cus-load status
erc-services erc-list erc-menu erc-join erc-ring erc-networks
erc-pcomplete pcomplete erc-track erc-match erc-button wid-edit
cl-loaddefs cl-lib erc-fill erc-stamp erc-netsplit erc-goodies erc
erc-backend erc-compat format-spec auth-source eieio byte-opt bytecomp
byte-compile cconv eieio-core gnus-util mm-util mail-prsvr
password-cache thingatpt pp advice help-fns vc-dir ewoc vc vc-dispatcher
cc-styles cc-align cc-engine cc-vars cc-defs bbdb timezone ange-ftp
comint ansi-color ring server savehist dwarf-mode-autoloads
jabber-autoloads lisppaste-autoloads pydoc-info-autoloads info-look info
easymenu weblogger-autoloads package epg-config bbdb-autoloads time-date
tooltip electric uniquify ediff-hook vc-hooks lisp-float-type mwheel
x-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list
newcomment elisp-mode lisp-mode prog-mode register page menu-bar
rfn-eshadow timer select scroll-bar mouse jit-lock font-lock syntax
facemenu font-core frame cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese hebrew greek romanian slovak
czech european ethiopic indian cyrillic chinese case-table epa-hook
jka-cmpr-hook help simple abbrev minibuffer nadvice loaddefs button
faces cus-face macroexp files text-properties overlay sha1 md5 base64
format env code-pages mule custom widget hashtable-print-readable
backquote make-network-process dbusbind gfilenotify dynamic-setting
system-font-setting font-render-setting move-toolbar gtk x-toolkit x
multi-tty emacs)
Memory information:
((conses 16 2621370 283762)
(symbols 48 136643 5)
(miscs 40 63207 11870)
(strings 32 404536 58294)
(string-bytes 1 18990197)
(vectors 16 116801)
(vector-slots 8 2921863 191230)
(floats 8 758 1153)
(intervals 56 289543 1523)
(buffers 976 821)
(heap 1024 349107 75634))
Tom
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18721: 25.0.50; choose major mode from .dir-locals.el
2014-10-14 20:06 bug#18721: 25.0.50; choose major mode from .dir-locals.el Tom Tromey
@ 2014-10-14 23:54 ` Stefan Monnier
2014-10-16 13:23 ` Ted Zlatanov
2017-01-15 2:38 ` bug#18721: patch Tom Tromey
1 sibling, 1 reply; 10+ messages in thread
From: Stefan Monnier @ 2014-10-14 23:54 UTC (permalink / raw)
To: Tom Tromey; +Cc: 18721
> It would be nice if there were a way to associate
> file extensions with major modes in .dir-locals.el.
> This would let projects use project-specific extensions
> without requiring per-file mode cookies or having
> everybody modify their .emacs
Indeed. Binding .tex to latex-mode would be a common use over here.
Stefan
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18721: 25.0.50; choose major mode from .dir-locals.el
2014-10-14 23:54 ` Stefan Monnier
@ 2014-10-16 13:23 ` Ted Zlatanov
0 siblings, 0 replies; 10+ messages in thread
From: Ted Zlatanov @ 2014-10-16 13:23 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Tom Tromey, 18721
On Tue, 14 Oct 2014 19:54:41 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>> It would be nice if there were a way to associate
>> file extensions with major modes in .dir-locals.el.
>> This would let projects use project-specific extensions
>> without requiring per-file mode cookies or having
>> everybody modify their .emacs
SM> Indeed. Binding .tex to latex-mode would be a common use over here.
I would use that, definitely.
Ted
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18721: patch
2014-10-14 20:06 bug#18721: 25.0.50; choose major mode from .dir-locals.el Tom Tromey
2014-10-14 23:54 ` Stefan Monnier
@ 2017-01-15 2:38 ` Tom Tromey
2017-01-15 15:33 ` Eli Zaretskii
1 sibling, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2017-01-15 2:38 UTC (permalink / raw)
To: 18721
This patch adds the feature described in this bug. There are a few
possible ways to do it, this picks a simple one: mimic auto-mode-alist
directly.
Let me know what you think.
thanks,
Tom
commit e13f5fdb86142e1b5bc3e8315a4219287da9c55b
Author: Tom Tromey <tom@tromey.com>
Date: Fri Jan 13 11:10:08 2017 -0700
Add auto-mode-alist functionality to .dir-locals.el
Bug#18721
* doc/emacs/custom.texi (Directory Variables): Document
auto-mode-alist in .dir-locals.el.
* doc/emacs/modes.texi (Choosing Modes): Update.
* lisp/files.el (set-auto-mode--apply-alist): New function,
from set-auto-mode.
(set-auto-mode): Check directory locals for auto-mode-alist.
(dir-locals-collect-variables): Add "predicate" parameter.
(hack-dir-local--get-variables): New function, from
hack-dir-local-variables.
(hack-dir-local-variables): Call hack-dir-local--get-variables.
* test/data/files-resources/.dir-locals.el: New file.
* test/data/files-resources/whatever.quux: New file.
* test/lisp/files-tests.el (files-tests-data-dir): New variable.
(files-test-dir-locals-auto-mode-alist): New test.
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index c84f4a9..2386cfd 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1351,6 +1351,16 @@ Directory Variables
cannot be specified as a directory local variable. @xref{File
Variables}.
+The special key @code{auto-mode-alist} in a @file{.dir-locals.el} lets
+you set a file's major mode. It works much like the variable
+@code{auto-mode-alist} (@pxref{Choosing Modes}). For example, here is
+how you can tell Emacs that @file{.def} source files in this directory
+should be in C mode:
+
+@example
+((auto-mode-alist . (("\\.def\\'" . c-mode))))
+@end example
+
@findex add-dir-local-variable
@findex delete-dir-local-variable
@findex copy-file-locals-to-dir-locals
diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi
index 0acb82d..04736a3 100644
--- a/doc/emacs/modes.texi
+++ b/doc/emacs/modes.texi
@@ -349,8 +349,12 @@ Choosing Modes
particular file type, it is better to enable the minor mode via a
major mode hook (@pxref{Major Modes}).
+ Second, Emacs checks whether the file's extension matches an entry
+in any directory-local @code{auto-mode-alist}. These are found using
+the @file{.dir-locals.el} facility (@pxref{Directory Variables}).
+
@vindex interpreter-mode-alist
- Second, if there is no file variable specifying a major mode, Emacs
+ Third, if there is no file variable specifying a major mode, Emacs
checks whether the file's contents begin with @samp{#!}. If so, that
indicates that the file can serve as an executable shell command,
which works by running an interpreter named on the file's first line
@@ -368,7 +372,7 @@ Choosing Modes
@samp{'\"} to specify a list of troff preprocessors.
@vindex magic-mode-alist
- Third, Emacs tries to determine the major mode by looking at the
+ Fourth, Emacs tries to determine the major mode by looking at the
text at the start of the buffer, based on the variable
@code{magic-mode-alist}. By default, this variable is @code{nil} (an
empty list), so Emacs skips this step; however, you can customize it
@@ -396,7 +400,7 @@ Choosing Modes
beginning of the buffer; if the function returns non-@code{nil}, Emacs
set the major mode with @var{mode-function}.
- Fourth---if Emacs still hasn't found a suitable major mode---it
+ Fifth---if Emacs still hasn't found a suitable major mode---it
looks at the file's name. The correspondence between file names and
major modes is controlled by the variable @code{auto-mode-alist}. Its
value is a list in which each element has this form,
diff --git a/lisp/files.el b/lisp/files.el
index b57e35b..6a59077 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2808,11 +2808,62 @@ magic-mode-regexp-match-limit
"Upper limit on `magic-mode-alist' regexp matches.
Also applies to `magic-fallback-mode-alist'.")
+(defun set-auto-mode--apply-alist (alist keep-mode-if-same dir-local)
+ "Helper function for `set-auto-mode'.
+This function takes an alist of the same form as
+`auto-mode-alist'. It then tries to find the appropriate match
+in the alist for the current buffer; setting the mode if
+possible. Returns non-`nil' if the mode was set, `nil'
+otherwise. DIR-LOCAL is a boolean which, if true, says that this
+call is via directory-locals and extra checks should be done."
+ (if buffer-file-name
+ (let (mode
+ (name buffer-file-name)
+ (remote-id (file-remote-p buffer-file-name))
+ (case-insensitive-p (file-name-case-insensitive-p
+ buffer-file-name)))
+ ;; Remove backup-suffixes from file name.
+ (setq name (file-name-sans-versions name))
+ ;; Remove remote file name identification.
+ (when (and (stringp remote-id)
+ (string-match (regexp-quote remote-id) name))
+ (setq name (substring name (match-end 0))))
+ (while name
+ ;; Find first matching alist entry.
+ (setq mode
+ (if case-insensitive-p
+ ;; Filesystem is case-insensitive.
+ (let ((case-fold-search t))
+ (assoc-default alist 'string-match))
+ ;; Filesystem is case-sensitive.
+ (or
+ ;; First match case-sensitively.
+ (let ((case-fold-search nil))
+ (assoc-default name alist 'string-match))
+ ;; Fallback to case-insensitive match.
+ (and auto-mode-case-fold
+ (let ((case-fold-search t))
+ (assoc-default name alist 'string-match))))))
+ (if (and mode
+ (consp mode)
+ (cadr mode))
+ (setq mode (car mode)
+ name (substring name 0 (match-beginning 0)))
+ (setq name nil)))
+ (when (and dir-local mode)
+ (unless (string-suffix-p "-mode" (symbol-name mode))
+ (message "Ignoring invalid mode `%s'" (symbol-name mode))
+ (setq mode nil)))
+ (when mode
+ (set-auto-mode-0 mode keep-mode-if-same)
+ t))))
+
(defun set-auto-mode (&optional keep-mode-if-same)
"Select major mode appropriate for current buffer.
To find the right major mode, this function checks for a -*- mode tag
checks for a `mode:' entry in the Local Variables section of the file,
+checks if there an `auto-mode-alist' entry in `.dir-locals.el',
checks if it uses an interpreter listed in `interpreter-mode-alist',
matches the buffer beginning against `magic-mode-alist',
compares the filename against the entries in `auto-mode-alist',
@@ -2869,6 +2920,14 @@ set-auto-mode
(or (set-auto-mode-0 mode keep-mode-if-same)
;; continuing would call minor modes again, toggling them off
(throw 'nop nil))))))
+ ;; Check for auto-mode-alist entry in dir-locals.
+ (unless done
+ (with-demoted-errors "Directory-local variables error: %s"
+ ;; Note this is a no-op if enable-local-variables is nil.
+ (let* ((mode-alist (cdr (hack-dir-local--get-variables
+ (lambda (key) (eq key 'auto-mode-alist))))))
+ (setq done (set-auto-mode--apply-alist mode-alist
+ keep-mode-if-same t)))))
;; hack-local-variables checks local-enable-local-variables etc, but
;; we might as well be explicit here for the sake of clarity.
(and (not done)
@@ -2917,45 +2976,8 @@ set-auto-mode
(set-auto-mode-0 done keep-mode-if-same)))
;; Next compare the filename against the entries in auto-mode-alist.
(unless done
- (if buffer-file-name
- (let ((name buffer-file-name)
- (remote-id (file-remote-p buffer-file-name))
- (case-insensitive-p (file-name-case-insensitive-p
- buffer-file-name)))
- ;; Remove backup-suffixes from file name.
- (setq name (file-name-sans-versions name))
- ;; Remove remote file name identification.
- (when (and (stringp remote-id)
- (string-match (regexp-quote remote-id) name))
- (setq name (substring name (match-end 0))))
- (while name
- ;; Find first matching alist entry.
- (setq mode
- (if case-insensitive-p
- ;; Filesystem is case-insensitive.
- (let ((case-fold-search t))
- (assoc-default name auto-mode-alist
- 'string-match))
- ;; Filesystem is case-sensitive.
- (or
- ;; First match case-sensitively.
- (let ((case-fold-search nil))
- (assoc-default name auto-mode-alist
- 'string-match))
- ;; Fallback to case-insensitive match.
- (and auto-mode-case-fold
- (let ((case-fold-search t))
- (assoc-default name auto-mode-alist
- 'string-match))))))
- (if (and mode
- (consp mode)
- (cadr mode))
- (setq mode (car mode)
- name (substring name 0 (match-beginning 0)))
- (setq name nil))
- (when mode
- (set-auto-mode-0 mode keep-mode-if-same)
- (setq done t))))))
+ (setq done (set-auto-mode--apply-alist auto-mode-alist
+ keep-mode-if-same nil)))
;; Next try matching the buffer beginning against magic-fallback-mode-alist.
(unless done
(if (setq done (save-excursion
@@ -3716,10 +3738,13 @@ dir-locals-collect-mode-variables
;; Need a new cons in case we setcdr later.
(push (cons variable value) variables)))))
-(defun dir-locals-collect-variables (class-variables root variables)
+(defun dir-locals-collect-variables (class-variables root variables
+ &optional predicate)
"Collect entries from CLASS-VARIABLES into VARIABLES.
ROOT is the root directory of the project.
-Return the new variables list."
+Return the new variables list.
+If PREDICATE is given, it is used to test a symbol key in the alist
+to see whether it should be considered."
(let* ((file-name (or (buffer-file-name)
;; Handle non-file buffers, too.
(expand-file-name default-directory)))
@@ -3737,9 +3762,11 @@ dir-locals-collect-variables
(>= (length sub-file-name) (length key))
(string-prefix-p key sub-file-name))
(setq variables (dir-locals-collect-variables
- (cdr entry) root variables))))
- ((or (not key)
- (derived-mode-p key))
+ (cdr entry) root variables predicate))))
+ ((if predicate
+ (funcall predicate key)
+ (or (not key)
+ (derived-mode-p key)))
(let* ((alist (cdr entry))
(subdirs (assq 'subdirs alist)))
(if (or (not subdirs)
@@ -3955,13 +3982,13 @@ enable-remote-dir-locals
(defvar hack-dir-local-variables--warned-coding nil)
-(defun hack-dir-local-variables ()
+(defun hack-dir-local--get-variables (predicate)
"Read per-directory local variables for the current buffer.
-Store the directory-local variables in `dir-local-variables-alist'
-and `file-local-variables-alist', without applying them.
-
-This does nothing if either `enable-local-variables' or
-`enable-dir-local-variables' are nil."
+Return a cons of the form (DIR . ALIST), where DIR is the
+directory name (maybe nil) and ALIST is an alist of all variables
+that might apply. These will be filtered according to the
+buffer's directory, but not according to its mode.
+PREDICATE is passed to `dir-locals-collect-variables'."
(when (and enable-local-variables
enable-dir-local-variables
(or enable-remote-dir-locals
@@ -3980,21 +4007,33 @@ hack-dir-local-variables
(setq dir-name (nth 0 dir-or-cache))
(setq class (nth 1 dir-or-cache))))
(when class
- (let ((variables
- (dir-locals-collect-variables
- (dir-locals-get-class-variables class) dir-name nil)))
- (when variables
- (dolist (elt variables)
- (if (eq (car elt) 'coding)
- (unless hack-dir-local-variables--warned-coding
- (setq hack-dir-local-variables--warned-coding t)
- (display-warning 'files
- "Coding cannot be specified by dir-locals"))
- (unless (memq (car elt) '(eval mode))
- (setq dir-local-variables-alist
- (assq-delete-all (car elt) dir-local-variables-alist)))
- (push elt dir-local-variables-alist)))
- (hack-local-variables-filter variables dir-name)))))))
+ (cons dir-name
+ (dir-locals-collect-variables
+ (dir-locals-get-class-variables class)
+ dir-name nil predicate))))))
+
+(defun hack-dir-local-variables ()
+ "Read per-directory local variables for the current buffer.
+Store the directory-local variables in `dir-local-variables-alist'
+and `file-local-variables-alist', without applying them.
+
+This does nothing if either `enable-local-variables' or
+`enable-dir-local-variables' are nil."
+ (let* ((items (hack-dir-local--get-variables nil))
+ (dir-name (car items))
+ (variables (cdr items)))
+ (when variables
+ (dolist (elt variables)
+ (if (eq (car elt) 'coding)
+ (unless hack-dir-local-variables--warned-coding
+ (setq hack-dir-local-variables--warned-coding t)
+ (display-warning 'files
+ "Coding cannot be specified by dir-locals"))
+ (unless (memq (car elt) '(eval mode))
+ (setq dir-local-variables-alist
+ (assq-delete-all (car elt) dir-local-variables-alist)))
+ (push elt dir-local-variables-alist)))
+ (hack-local-variables-filter variables dir-name))))
(defun hack-dir-local-variables-non-file-buffer ()
"Apply directory-local variables to a non-file buffer.
diff --git a/test/data/files-resources/.dir-locals.el b/test/data/files-resources/.dir-locals.el
new file mode 100644
index 0000000..84997b8
--- /dev/null
+++ b/test/data/files-resources/.dir-locals.el
@@ -0,0 +1,2 @@
+;; This is used by files-tests.el.
+((auto-mode-alist . (("\\.quux\\'" . tcl-mode))))
diff --git a/test/data/files-resources/whatever.quux b/test/data/files-resources/whatever.quux
new file mode 100644
index 0000000..595583b
--- /dev/null
+++ b/test/data/files-resources/whatever.quux
@@ -0,0 +1,2 @@
+# Used by files-test.el.
+# Due to .dir-locals.el this should end up in Tcl mode.
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index 9d456c5..c0dd800 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -25,6 +25,11 @@
;; triggered.
(defvar files-test-result nil)
+;; Where supplementary files can be found.
+(defvar files-tests-data-dir
+ (expand-file-name "data/files-resources/"
+ (getenv "EMACS_TEST_DIRECTORY")))
+
(defvar files-test-safe-result nil)
(put 'files-test-safe-result 'safe-local-variable 'booleanp)
@@ -243,5 +248,10 @@ files-test-bug-18141-file
(concat "/:/:" subdir)))))
(delete-directory dir 'recursive))))
+(ert-deftest files-test-dir-locals-auto-mode-alist ()
+ "Test an `auto-mode-alist' entry in `.dir-locals.el'"
+ (find-file (expand-file-name "whatever.quux" files-tests-data-dir))
+ (should (eq major-mode 'tcl-mode)))
+
(provide 'files-tests)
;;; files-tests.el ends here
^ permalink raw reply related [flat|nested] 10+ messages in thread
* bug#18721: patch
2017-01-15 2:38 ` bug#18721: patch Tom Tromey
@ 2017-01-15 15:33 ` Eli Zaretskii
2017-01-15 19:22 ` Eli Zaretskii
2017-01-16 19:17 ` Tom Tromey
0 siblings, 2 replies; 10+ messages in thread
From: Eli Zaretskii @ 2017-01-15 15:33 UTC (permalink / raw)
To: Tom Tromey; +Cc: 18721
> From: Tom Tromey <tom@tromey.com>
> Date: Sat, 14 Jan 2017 19:38:02 -0700
>
> This patch adds the feature described in this bug. There are a few
> possible ways to do it, this picks a simple one: mimic auto-mode-alist
> directly.
>
> Let me know what you think.
Thanks. This will need a NEWS entry. Also, I have a comment/concern:
> +The special key @code{auto-mode-alist} in a @file{.dir-locals.el} lets
> +you set a file's major mode. It works much like the variable
> address@hidden (@pxref{Choosing Modes}). For example, here is
> +how you can tell Emacs that @file{.def} source files in this directory
> +should be in C mode:
> +
> +@example
> +((auto-mode-alist . (("\\.def\\'" . c-mode))))
> +@end example
I'm concerned that this syntax deviates from the current syntax of
.dir-locals.el, which is this:
(KEY . ((VARIABLE1 . VALUE1) (VARIABLE2 . VALUE2) ...))
where KEY can be:
. nil, meaning it's applicable to any file in the directory tree;
. a major mode (not relevant to this discussion)
. a subdirectory name, meaning the setting is applicable to files in
that subdirectory
Your suggestion uses a form of just (VARIABLE . VALUE), effectively
using the variable name as KEY, which differs from the above, and also
loses the capability of specifying a value only for some subdirectory.
So I'm asking why not keep the current syntax for this feature, and
avoid introducing a new kind of special key? This would mean your
example above will look like this:
(nil . ((auto-mode-alist . (("\\.def\\'" . c-mode)))))
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18721: patch
2017-01-15 15:33 ` Eli Zaretskii
@ 2017-01-15 19:22 ` Eli Zaretskii
2017-01-16 19:17 ` Tom Tromey
1 sibling, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2017-01-15 19:22 UTC (permalink / raw)
To: tom; +Cc: 18721
> Date: Sun, 15 Jan 2017 17:33:30 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: 18721@debbugs.gnu.org
>
> Thanks. This will need a NEWS entry. Also, I have a comment/concern:
Oh, and one more nit: .dir-locals.el is documented to apply to remote
files if enable-remote-dir-locals is non-nil. But, unless I
misunderstood your code, it exempts remote files unconditionally,
which contradicts the documentation.
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18721: patch
2017-01-15 15:33 ` Eli Zaretskii
2017-01-15 19:22 ` Eli Zaretskii
@ 2017-01-16 19:17 ` Tom Tromey
2021-05-29 4:07 ` bug#18188: Please make it possible to have a directory-local setting for auto-mode-alist Lars Ingebrigtsen
1 sibling, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2017-01-16 19:17 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Tom Tromey, 18721
>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes:
Eli> So I'm asking why not keep the current syntax for this feature, and
Eli> avoid introducing a new kind of special key? This would mean your
Eli> example above will look like this:
Eli> (nil . ((auto-mode-alist . (("\\.def\\'" . c-mode)))))
I suppose it would work ok as long as the code also doesn't try to set
auto-mode-alist locally in the buffer, both because that variable isn't
safe, and because I think it doesn't make sense to set it buffer-locally
anyhow.
Eli> Oh, and one more nit: .dir-locals.el is documented to apply to
Eli> remote files if enable-remote-dir-locals is non-nil. But, unless I
Eli> misunderstood your code, it exempts remote files unconditionally,
Eli> which contradicts the documentation.
I think this should work ok because hack-dir-local--get-variables checks
enable-remote-dir-locals. In this case it will return nil, so the new
code in set-auto-mode will not do anything.
Tom
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18188: Please make it possible to have a directory-local setting for auto-mode-alist
2017-01-16 19:17 ` Tom Tromey
@ 2021-05-29 4:07 ` Lars Ingebrigtsen
2021-05-29 15:13 ` Tom Tromey
0 siblings, 1 reply; 10+ messages in thread
From: Lars Ingebrigtsen @ 2021-05-29 4:07 UTC (permalink / raw)
To: Tom Tromey; +Cc: 18721, 18188
Tom Tromey <tom@tromey.com> writes:
> Eli> So I'm asking why not keep the current syntax for this feature, and
> Eli> avoid introducing a new kind of special key? This would mean your
> Eli> example above will look like this:
> Eli> (nil . ((auto-mode-alist . (("\\.def\\'" . c-mode)))))
>
> I suppose it would work ok as long as the code also doesn't try to set
> auto-mode-alist locally in the buffer, both because that variable isn't
> safe, and because I think it doesn't make sense to set it buffer-locally
> anyhow.
I think everybody agreed that this was a good feature to add (with Eli's
tweaks), but as far as I can tell, it was never added. Tom, would it be
possible for you to re-spin this patch for Emacs 28?
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18188: Please make it possible to have a directory-local setting for auto-mode-alist
2021-05-29 4:07 ` bug#18188: Please make it possible to have a directory-local setting for auto-mode-alist Lars Ingebrigtsen
@ 2021-05-29 15:13 ` Tom Tromey
2021-07-23 14:00 ` bug#18188: bug#18721: 25.0.50; choose major mode from .dir-locals.el Lars Ingebrigtsen
0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2021-05-29 15:13 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: Tom Tromey, 18721, 18188
Lars> I think everybody agreed that this was a good feature to add (with Eli's
Lars> tweaks), but as far as I can tell, it was never added. Tom, would it be
Lars> possible for you to re-spin this patch for Emacs 28?
Doubtful, but it's fine by me if someone takes it over. I don't recall
who objected or why, but someone didn't like the approach I took and
requested changes, so whoever does it would have to navigate this.
Tom
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#18188: bug#18721: 25.0.50; choose major mode from .dir-locals.el
2021-05-29 15:13 ` Tom Tromey
@ 2021-07-23 14:00 ` Lars Ingebrigtsen
0 siblings, 0 replies; 10+ messages in thread
From: Lars Ingebrigtsen @ 2021-07-23 14:00 UTC (permalink / raw)
To: Tom Tromey; +Cc: 18721, 18188
Tom Tromey <tom@tromey.com> writes:
> Lars> I think everybody agreed that this was a good feature to add (with Eli's
> Lars> tweaks), but as far as I can tell, it was never added. Tom, would it be
> Lars> possible for you to re-spin this patch for Emacs 28?
>
> Doubtful, but it's fine by me if someone takes it over. I don't recall
> who objected or why, but someone didn't like the approach I took and
> requested changes, so whoever does it would have to navigate this.
I've now respun the patch for Emacs 28, and it seems to work fine, and I
think everybody agreed that this was useful functionality.
There was some discussion about whether to introduce a new dir-locals
element for this, or just use the normal variable-setting thing. As Tom
said, the normal thing is awkward to use here (because of the
buffer-local thing), so I think Tom's approach here is the best,
overall.
So I've now pushed this to Emacs 28.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-07-23 14:00 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-14 20:06 bug#18721: 25.0.50; choose major mode from .dir-locals.el Tom Tromey
2014-10-14 23:54 ` Stefan Monnier
2014-10-16 13:23 ` Ted Zlatanov
2017-01-15 2:38 ` bug#18721: patch Tom Tromey
2017-01-15 15:33 ` Eli Zaretskii
2017-01-15 19:22 ` Eli Zaretskii
2017-01-16 19:17 ` Tom Tromey
2021-05-29 4:07 ` bug#18188: Please make it possible to have a directory-local setting for auto-mode-alist Lars Ingebrigtsen
2021-05-29 15:13 ` Tom Tromey
2021-07-23 14:00 ` bug#18188: bug#18721: 25.0.50; choose major mode from .dir-locals.el Lars Ingebrigtsen
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).