* 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).