From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Neil Roberts Newsgroups: gmane.emacs.bugs Subject: bug#33400: [PATCH] Let dir locals for more specific modes override those from less Date: Thu, 15 Nov 2018 19:01:17 +0100 Message-ID: <20181115180117.10423-1-bpeeluk@yahoo.co.uk> References: <87tvkiwk6g.fsf@yahoo.co.uk> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1542304940 10052 195.159.176.226 (15 Nov 2018 18:02:20 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 15 Nov 2018 18:02:20 +0000 (UTC) To: 33400@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Nov 15 19:02:16 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gNLy2-0002VT-GT for geb-bug-gnu-emacs@m.gmane.org; Thu, 15 Nov 2018 19:02:16 +0100 Original-Received: from localhost ([::1]:40174 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gNM08-0008A0-Vp for geb-bug-gnu-emacs@m.gmane.org; Thu, 15 Nov 2018 13:04:25 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34001) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gNLz1-0007Rz-DK for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 13:03:18 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gNLyo-0006i9-R7 for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 13:03:09 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:50162) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gNLyo-0006gn-EC for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 13:03:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gNLyo-0001t5-5x for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 13:03:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Neil Roberts Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 15 Nov 2018 18:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 33400 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.15423049486203 (code B ref -1); Thu, 15 Nov 2018 18:03:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 15 Nov 2018 18:02:28 +0000 Original-Received: from localhost ([127.0.0.1]:54420 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gNLyF-0001bb-Va for submit@debbugs.gnu.org; Thu, 15 Nov 2018 13:02:28 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:52093) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gNLyD-0001X2-Q5 for submit@debbugs.gnu.org; Thu, 15 Nov 2018 13:02:26 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gNLy5-0004L5-Cz for submit@debbugs.gnu.org; Thu, 15 Nov 2018 13:02:20 -0500 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:35450) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gNLy0-00042x-QD for submit@debbugs.gnu.org; Thu, 15 Nov 2018 13:02:13 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:33300) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gNLxy-0006ji-N9 for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 13:02:12 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gNLxt-0003WW-2V for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 13:02:09 -0500 Original-Received: from fanzine.igalia.com ([91.117.99.155]:42904) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gNLxj-0002d1-Be for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 13:01:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:To:From; bh=UW2kPNEHE0PHxNYZkBHUVxc4wZxsA9jVxZPKOimuLQw=; b=d2KsOFwF10u7C6x05CTemlk2idoGOzIOdT+feLnMHH9HRpXl9H8/JFBqmmHjiJWp2GD87NBmqsN64C67VdVKRSuwqXChqfXEn83Nk9r60v4oKgZMGrarpmpe9vT3SCjWaWXKsOmpMQpn5zteow5w05V22yDelm0Pm4CORKC/6PKnDokuXXfCmnl8RD8ZuPQtgfJpXufU5y6Zqyu4mArfqqYH1PteR7Ycf3EaqAa9xKKjpjv+PMY73chPaY9kGuLrer/0JSACIAVhOeQa0eu7jro2n3wYgmluBDZwwJ3Vix0jkprOonkRDO5k3txOu+ya/z5CKMKD/4kpyOQoGANPIA==; Original-Received: from lns-bzn-38-82-253-104-2.adsl.proxad.net ([82.253.104.2] helo=localhost.localdomain) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1gNLxf-0005pq-9f for ; Thu, 15 Nov 2018 19:01:51 +0100 X-Mailer: git-send-email 2.17.1 In-Reply-To: <87tvkiwk6g.fsf@yahoo.co.uk> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:152426 Archived-At: The list of dir local variables to apply is now sorted by the number of parent modes of the mode used as the key in the association list. That way when the variables are applied in order the variables from more specific modes will override those from less specific modes. If there are directory entries in the list then they are sorted in order of name length. The list of modes for that dir is then recursively sorted with the same mechanism. That way variables tied to a particular subdirectory override those in in a parent directory. Previously the behaviour didn’t seem to be well defined anyway and was dependent on the order they appeared in the file. However this order was changed in version 26.1 and it probably also depended on the number of dir-local files that are merged. Bug#33400 --- lisp/files.el | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/lisp/files.el b/lisp/files.el index dbac6f614f..09bee6a5f9 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4093,6 +4093,51 @@ dir-locals-find-file (declare-function map-merge-with "map" (type function &rest maps)) (declare-function map-merge "map" (type &rest maps)) +(defun dir-locals-get-sort-score (node) + "Return a number used for sorting the definitions of dir locals. +NODE is assumed to be a cons cell where the car is either a +string or a symbol representing a mode name. + +If it is a mode then the the depth of the mode (ie, how many +parents that mode has) will be returned. + +If it is a string then the length of the string plus 1000 will be +returned. + +Otherwise it returns -1. + +That way the value can be used to sort the list such that deeper +modes will be after the other modes. This will be followed by +directory entries in order of length. If the entries are all +applied in order then that means the more specific modes will +override the values specified by the earlier modes and directory +variables will override modes." + (let ((key (car node))) + (cond ((null key) -1) + ((symbolp key) + (let ((mode key) + (depth 0)) + (while (setq mode (get mode 'derived-mode-parent)) + (setq depth (1+ depth))) + depth)) + ((stringp key) + (+ 1000 (length key))) + (t -2)))) + +(defun dir-locals-sort-variables (variables) + "Sorts VARIABLES so that applying them in order has the right effect. +The variables are compared by dir-locals-get-sort-score. Directory entries +are then recursively sorted using the same criteria." + (setq variables (sort variables + (lambda (a b) + (< (dir-locals-get-sort-score a) + (dir-locals-get-sort-score b))))) + (dolist (n variables) + (when (stringp (car n)) + (setcdr n (dir-locals-sort-variables (cdr n))))) + + variables) + (defun dir-locals-read-from-dir (dir) "Load all variables files in DIR and register a new class and instance. DIR is the absolute name of a directory which must contain at @@ -4130,6 +4175,7 @@ dir-locals-read-from-dir variables newvars)))))) (setq success latest)) + (setq variables (dir-locals-sort-variables variables)) (dir-locals-set-class-variables class-name variables) (dir-locals-set-directory-class dir class-name success) class-name)) -- 2.17.1