GNU bug report logs - #30008
27.0.50; Subdirectory vs major mode in .dir-locals.el

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: kevin.legouguec@HIDDEN (Kévin Le Gouguec); dated Sat, 6 Jan 2018 17:48:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.
bug Marked as found in versions 26.0.90. Request was from kevin.legouguec@HIDDEN (Kévin Le Gouguec) to control <at> Full text available.

Message received at submit <at>

Received: (at submit) by; 6 Jan 2018 17:47:07 +0000
From debbugs-submit-bounces <at> Sat Jan 06 12:47:07 2018
Received: from localhost ([]:38378
	by with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at>>)
	id 1eXsYl-0002Q3-5o
	for submit <at>; Sat, 06 Jan 2018 12:47:07 -0500
Received: from ([]:60100)
 by with esmtp (Exim 4.84_2)
 (envelope-from <kevin.legouguec@HIDDEN>) id 1eXsYj-0002PW-50
 for submit <at>; Sat, 06 Jan 2018 12:47:05 -0500
Received: from Debian-exim by with spam-scanned (Exim 4.71)
 (envelope-from <kevin.legouguec@HIDDEN>) id 1eXsYc-0006bd-CR
 for submit <at>; Sat, 06 Jan 2018 12:46:59 -0500
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on
X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM,
 T_DKIM_INVALID,URIBL_BLOCKED autolearn=disabled version=3.3.2
Received: from ([2001:4830:134:3::11]:32853)
 by with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
 (Exim 4.71) (envelope-from <kevin.legouguec@HIDDEN>)
 id 1eXsYc-0006aw-6W
 for submit <at>; Sat, 06 Jan 2018 12:46:58 -0500
Received: from ([2001:4830:134:3::10]:51028)
 by with esmtp (Exim 4.71)
 (envelope-from <kevin.legouguec@HIDDEN>) id 1eXsYa-0004oA-66
 for bug-gnu-emacs@HIDDEN; Sat, 06 Jan 2018 12:46:57 -0500
Received: from Debian-exim by with spam-scanned (Exim 4.71)
 (envelope-from <kevin.legouguec@HIDDEN>) id 1eXsYV-0006So-54
 for bug-gnu-emacs@HIDDEN; Sat, 06 Jan 2018 12:46:56 -0500
Received: from ([2a00:1450:400c:c0c::22b]:35945)
 by with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16)
 (Exim 4.71) (envelope-from <kevin.legouguec@HIDDEN>)
 id 1eXsYU-0006RW-OZ
 for bug-gnu-emacs@HIDDEN; Sat, 06 Jan 2018 12:46:51 -0500
Received: by with SMTP id b76so6992524wrd.3
 for <bug-gnu-emacs@HIDDEN>; Sat, 06 Jan 2018 09:46:50 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025;
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025;
X-Gm-Message-State: AKGB3mK5bwe1fizenBQg2fSTpBHh+KgB/Eaxqz4zLP0szaRrMOmm+c67
X-Google-Smtp-Source: ACJfBovC7p40t/y8ToOccYr4j/oX0PbgVgM0RtUvmpiBeU7tUh5yClmBd/tOdB18Bry1AqiHcaeorw==
X-Received: by with SMTP id l6mr5802703wrb.162.1515260808754;
 Sat, 06 Jan 2018 09:46:48 -0800 (PST)
Received: from nc10-laptop (
 by with ESMTPSA id b42sm7412939wrg.48.2018.
 for <bug-gnu-emacs@HIDDEN>
 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
 Sat, 06 Jan 2018 09:46:47 -0800 (PST)
From: kevin.legouguec@HIDDEN (=?utf-8?Q?K=C3=A9vin?= Le Gouguec)
To: bug-gnu-emacs@HIDDEN
Subject: 27.0.50; Subdirectory vs major mode in .dir-locals.el
Date: Sat, 06 Jan 2018 18:46:45 +0100
Message-ID: <87inceani2.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-detected-operating-system: by Genre and OS details not
X-detected-operating-system: by GNU/Linux 2.6.x
X-Received-From: 2001:4830:134:3::11
X-Spam-Score: -4.0 (----)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at>
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <>
List-Unsubscribe: <>, 
 <mailto:debbugs-submit-request <at>>
List-Archive: <>
List-Post: <mailto:debbugs-submit <at>>
List-Help: <mailto:debbugs-submit-request <at>>
List-Subscribe: <>, 
 <mailto:debbugs-submit-request <at>>
Errors-To: debbugs-submit-bounces <at>
Sender: "Debbugs-submit" <debbugs-submit-bounces <at>>
X-Spam-Score: -4.0 (----)

Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable


While fiddling with directory-local variables, I think I stumbled on a
change of behavior between Emacs 25 and 26.

Given the following .dir-locals.el file:

      . ((my-list . (1 2 3))))
      . ((c-mode
          . ((my-list . (1 2 3 4 5 6)))))))

And the following directory structure:

    =E2=94=9C=E2=94=80=E2=94=80 .dir-locals.el
    =E2=94=94=E2=94=80=E2=94=80 subdir
        =E2=94=94=E2=94=80=E2=94=80 foo.c

my-list gets different values depending on whether I open subdir/foo.c
with Emacs 25 or 26.  With 25, my-list equals (1 2 3 4 5 6); with 26,
my-list equals (1 2 3).

If I transpose the first (c-mode =E2=80=A6) sexp with the ("subdir" =E2=80=
=A6) one:

      . ((c-mode
          . ((my-list . (1 2 3 4 5 6))))))
      . ((my-list . (1 2 3)))))

Then opening subdir/foo.c in Emacs 25 yields (1 2 3), while in 26 I
get (1 2 3 4 5 6).

I attached some scripts to reproduce the issue[1].  I skimmed
etc/NEWS.26 and (emacs)Directory Variables, but I did not find
anything suggesting that this change was deliberate, or which
behavior is "officially intended".

I haven't looked at the code yet, so I do not know if this change lies
more toward "obviously incorrect refactoring accident", "deliberate
and logical if you think about it", or something else.

AFAICT, there are two questions to answer:

- Which behavior should be kept?
- Should it be documented?

(Assuming what I observe is indeed due to an undocumented change;
maybe nothing changed and my setup is to blame, or the change *is*
documented and I missed the memo)

Since I can work around this change, I don't feel strongly about
either behavior.  I might find the old one more intuitive ("look for
definitions that match the major mode and the subfolder, apply the
last one"), but the new one also makes sense ("apply the first
definition that matches").

As for documentation, perhaps "multiple definitions in a single
.dir-locals.el file" is something of a weird edge case.  In that case,
maybe it's not worth setting it in stone, so that the code can keep
some wiggle room.

tl;dr: close this as soon as you're done reading I guess =F0=9F=98=9B

[1]: Sample output:

    $ ./
      . ((my-list . (1 2 3))))
      . ((c-mode
          . ((my-list . (1 2 3 4 5 6)))))))
    Opening subdir/foo.c with=E2=80=A6 (c3ff6712ad24fcf45874dc0665a8606e9b2208a4): (1 2 3 4 5 6)
    26.0.90 (aa66da220cdb6aaab5b347093fd40f0e1580913b): (1 2 3)
    27.0.50 (8e13d3ab1a31c3f5aee19ee7a92ddaed5fc3eb2d): (1 2 3)

      . ((c-mode
          . ((my-list . (1 2 3 4 5 6))))))
      . ((my-list . (1 2 3)))))
    Opening subdir/foo.c with=E2=80=A6 (c3ff6712ad24fcf45874dc0665a8606e9b2208a4): (1 2 3)
    26.0.90 (aa66da220cdb6aaab5b347093fd40f0e1580913b): (1 2 3 4 5 6)
    27.0.50 (8e13d3ab1a31c3f5aee19ee7a92ddaed5fc3eb2d): (1 2 3 4 5 6) assumes that

- the attached Elisp files are in the same folder:

    =E2=94=9C=E2=94=80=E2=94=80 subdir-after.el
    =E2=94=9C=E2=94=80=E2=94=80 subdir-before.el
    =E2=94=94=E2=94=80=E2=94=80 test.el

- emacs-{25,26,master} resolve to something executable; in my case:

    =E2=94=9C=E2=94=80=E2=94=80 emacs-25 -> ~/Downloads/sources/emacs-25/sr=
    =E2=94=9C=E2=94=80=E2=94=80 emacs-26 -> ~/Downloads/sources/emacs-26/sr=
    =E2=94=94=E2=94=80=E2=94=80 emacs-master -> ~/Downloads/sources/emacs/s=

In GNU Emacs 27.0.50 (build 6, i686-pc-linux-gnu, GTK+ Version 3.14.5)
 of 2017-12-14 built on nc10-laptop
Repository revision: 8e13d3ab1a31c3f5aee19ee7a92ddaed5fc3eb2d
Windowing system distributor 'The X.Org Foundation', version 11.0.11604000
System Description: BunsenLabs GNU/Linux 8.9 (Hydrogen)

Configured using:
 'configure --with-xwidgets --with-x-toolkit=3Dgtk3'

Configured features:

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Text

Minor modes in effect:
  scroll-lock-mode: t
  flyspell-mode: t
  shell-dirtrack-mode: t
  show-paren-mode: t
  icomplete-mode: t
  global-page-break-lines-mode: t
  page-break-lines-mode: t
  electric-pair-mode: t
  delete-selection-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-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: do-auto-fill
  visual-line-mode: t
  transient-mark-mode: t

Load-path shadows:
/home/snip/.emacs.d/elpa/seq-20151121.1017/seq hides /home/snip/Downloads/s=

(shadow sort mail-extr emacsbug sendmail gnus-async qp gnus-ml nndraft
nnmh nnfolder utf-7 epa-file network-stream nsm starttls gnus-agent
gnus-srvr gnus-score score-mode nnvirtual gnus-msg gnus-art mm-uu
mml2015 mm-view mml-smime smime dig mailcap nntp gnus-cache gnus-sum
gnus-group gnus-undo gnus-start gnus-cloud nnimap nnmail mail-source tls
gnutls utf7 netrc nnoo parse-time gnus-spec gnus-int gnus-range message
rmc puny format-spec rfc822 mml mml-sec epa derived epg mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
gnus-win gnus nnheader gnus-util rmail rmail-loaddefs rfc2047 rfc2045
ietf-drums mail-utils mm-util mail-prsvr dired-aux wid-edit descr-text
markdown-mode rx color thingatpt noutline outline easy-mmode scroll-lock
flyspell face-remap iso-transl info-look tabify imenu man shell
pcomplete sh-script smie misearch multi-isearch ispell executable dired
dired-loaddefs delight advice eighters-theme quail cl-extra help-mode rg
s ibuf-ext ibuffer ibuffer-loaddefs grep compile comint ansi-color ring
edmacro kmacro disp-table paren icomplete page-break-lines elec-pair
delsel cus-start cus-load finder-inf info package easymenu epg-config
url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs
eieio-loaddefs password-cache url-vars seq byte-opt gv bytecomp
byte-compile cconv cl-loaddefs cl-lib time-date mule-util tooltip eldoc
electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win
x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode
prog-mode register page menu-bar rfn-eshadow isearch timer select
scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang
vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932
hebrew greek romanian slovak czech european ethiopic indian cyrillic
chinese composite charscript charprop case-table epa-hook jka-cmpr-hook
help simple abbrev obarray minibuffer cl-preloaded 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 dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting xwidget-internal move-toolbar gtk x-toolkit x
multi-tty make-network-process emacs)

Memory information:
((conses 8 360934 34337)
 (symbols 24 50464 2)
 (miscs 20 785 1669)
 (strings 16 157140 4077)
 (string-bytes 1 4109553)
 (vectors 12 47141)
 (vector-slots 4 2021200 80958)
 (floats 8 394 582)
 (intervals 28 1976 261)
 (buffers 536 34)
 (heap 1024 60853 2288))

Content-Type: application/emacs-lisp
Content-Disposition: attachment; filename=test.el
Content-Transfer-Encoding: quoted-printable

(put 'my-list 'safe-local-variable (lambda (&rest args) t))
(find-file "subdir/foo.c")
(message (format "%s (%s): %s"
                 emacs-version emacs-repository-version my-list))

Content-Type: text/x-sh; charset=utf-8
Content-Disposition: attachment;
Content-Transfer-Encoding: quoted-printable


set -e

# Create a temporary directory to make sure we do not overwrite
# someone's .dir-locals.el=E2=80=A6

tmp=3D$(mktemp -d -p .)
    cd ${tmp}

    mkdir -p subdir
    touch subdir/foo.c

    for f in ../subdir-{after,before}.el
        tee .dir-locals.el < ${f}
        echo "Opening subdir/foo.c with=E2=80=A6"

        for e in emacs-{25,26,master}
            $e -Q --script ../test.el

rm -r ${tmp}

Content-Type: application/emacs-lisp
Content-Disposition: attachment; filename=subdir-before.el
Content-Transfer-Encoding: quoted-printable

  . ((c-mode
      . ((my-list . (1 2 3 4 5 6))))))
  . ((my-list . (1 2 3)))))

Content-Type: application/emacs-lisp
Content-Disposition: attachment; filename=subdir-after.el
Content-Transfer-Encoding: quoted-printable

  . ((my-list . (1 2 3))))
  . ((c-mode
      . ((my-list . (1 2 3 4 5 6)))))))


Acknowledgement sent to kevin.legouguec@HIDDEN (Kévin Le Gouguec):
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#30008; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Mon, 8 Jan 2018 19:00:02 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.