वहाँ डेज़ी श्रृंखला। Dir-locals.el फ़ाइलों के लिए एक रास्ता है?


15

मान लीजिए कि मेरे पास इन फाइलों के साथ एक निर्देशिका है।

/foo/bar/baz/.dir-locals.el
/foo/bar/.dir-locals.el
/foo/.dir-locals.el

जब मैं एक फ़ाइल बनाने के लिए जाता /foo/bar/baz/हूं, तो मैं उन्हें एक साथ श्रृंखला देना चाहूंगा जो /foo/.dir-locals.elपहले लागू होता है, और फिर /foo/bar/.dir-locals.el, और फिर/foo/bar/baz/.dir-locals.el



कोई विकल्प है कि क्या करना होगा कि (मैं बहुत बारीकी से कोड को देखा) है, लेकिन यह होना चाहिए (लगभग निश्चित रूप से है) के लिए कुछ अतिरिक्त कोड के साथ संभव। मेरे पास इसके लिए भी उपयोग है, इसलिए मैं इस पर गौर कर सकता हूं ...
कॉन्स्टेंटाइन

अपरिहार्य के साथ, सभी चीजें संभव हैं। :)
एरिक जॉनसन

जवाबों:


7

यहाँ जवाब के आधार पर , हम hack-dir-local-variablesएक निर्देशिका को देखने और चेक लोड करने की सलाह देकर ऐसा करते हैं यदि वह .dir-locals.elफ़ाइल पठनीय है। यह तब तक ऊपर जाता रहेगा जब तक यह एक निर्देशिका नहीं पढ़ता है .dir-locals.el

walk-dir-locals-upwardफाइलों के मूल्य के आधार पर वर्तमान निर्देशिका से ऊपर की ओर या पिछले .dir-locals.elपाए गए नीचे से पढ़ा जा सकता है। डाउनवर्ड डिफ़ॉल्ट है ताकि उपनिर्देशिका अपने माता-पिता की सेटिंग को रोक सकें।

(defvar walk-dir-locals-upward nil
  "If non-nil, evaluate .dir-locals.el files starting in the
  current directory and going up. Otherwise they will be
  evaluated from the top down to the current directory.")

(defadvice hack-dir-local-variables (around walk-dir-locals-file activate)
  (let* ((dir-locals-list (list dir-locals-file))
         (walk-dir-locals-file (first dir-locals-list)))
    (while (file-readable-p (concat "../" walk-dir-locals-file))
      (progn
        (setq walk-dir-locals-file (concat "../" walk-dir-locals-file))
        (add-to-list 'dir-locals-list walk-dir-locals-file
                     walk-dir-locals-upward)
        ))
    (dolist (file dir-locals-list)
      (let ((dir-locals-file (expand-file-name file)))
        (message dir-locals-file)
        ad-do-it
        )))
  )

यह उम्मीद करता है कि पेड़ की हर निर्देशिका (वर्तमान पथ से कुछ स्तर तक) एक है .dir-locals.el। क्या यह काम करेगा अगर मेरे पास निर्देशिकाओं का एक पेड़ है a/b/cऔर वहां मौजूद है a/.dir-locals.elऔर a/b/c/.dir-locals.el, लेकिन नहीं a/b/.dir-locals.el(मान लें कि मैं दौरा कर रहा हूं a/b/c/foo.elऔर मैं चाहता हूं कि सेटिंग्स a/.dir-locals.elलागू की जाएं)?
कॉन्स्टैंटाइन

1
हां, मैं यही मान रहा हूं। a/b/श्रृंखला को तोड़ने में लापता दिर-स्थानीय । इसे कहीं रोकना होगा और अगर आप चाहते हैं कि यह जारी रहे तो आप एक खाली डायर-लोकल फाइल जोड़ सकते हैं।
एरिकास्टोक्स

3
Btw, मैं बॉक्स के बाहर dir- स्थानीय लोगों का पीछा करने के लिए Emacs के लिए एक पैच का स्वागत करता हूँ।
स्टेफेन

6

यहाँ यह करने का एक अलग तरीका है।

मैं एक फ़ंक्शन को परिभाषित करता हूं जो वर्तमान निर्देशिका पदानुक्रम में सभी निर्देशिकाओं की सूची तैयार करता है।

(defun file-name-directory-nesting-helper (name previous-name accumulator)
  (if (string= name previous-name)
      accumulator                       ; stop when names stop changing (at the top)
      (file-name-directory-nesting-helper
       (directory-file-name (file-name-directory name))
       name
       (cons name accumulator))))

(defun file-name-directory-nesting (name)
  (file-name-directory-nesting-helper (expand-file-name name) "" ()))

एक उदाहरण क्रम में है:

(file-name-directory-nesting "/foo/bar/baz/quux/foo.el")
;; => ("/" "/foo" "/foo/bar" "/foo/bar/baz" "/foo/bar/baz/quux" "/foo/bar/baz/quux/foo.el")

अब मैं hack-dir-local-variablesइसे "दिखावा" बनाने के लिए सलाह जोड़ सकता हूं कि हम पेड़ के बहुत ऊपर एक फ़ाइल पर जा रहे हैं, निर्देशिका-स्थानीय सेटिंग्स लागू करें, फिर एक स्तर नीचे ले जाएं, फिर से सेटिंग्स लागू करें, और इसी तरह।

(defun hack-dir-local-variables-chained-advice (orig)
  "Apply dir-local settings from the whole directory hierarchy,
from the top down."
  (let ((original-buffer-file-name (buffer-file-name))
        (nesting (file-name-directory-nesting (or (buffer-file-name)
                                                  default-directory))))
    (unwind-protect
        (dolist (name nesting)
          ;; make it look like we're in a directory higher up in the
          ;; hierarchy; note that the file we're "visiting" does not
          ;; have to exist
          (setq buffer-file-name (expand-file-name "ignored" name))
          (funcall orig))
      ;; cleanup
      (setq buffer-file-name original-buffer-file-name))))

(advice-add 'hack-dir-local-variables :around
            #'hack-dir-local-variables-chained-advice)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.