2011-02-28 17 views
7

मैं निम्नलिखित सामग्री के साथ एक .dir-locals.el फ़ाइल को परिभाषित किया है:मैं अपने प्रमुख मोड हुक में निर्देशिका-स्थानीय चर का उपयोग कैसे कर सकता हूं?

(defun cr/virtualenv() 
    (cond (cr/virtualenv-name (format "%s/%s" virtualenv-base cr/virtualenv-name)) 
     ((getenv "EMACS_VIRTUAL_ENV") (getenv "EMACS_VIRTUAL_ENV")) 
     (t "~/.emacs.d/python"))) 
:

((python-mode . ((cr/virtualenv-name . "saas")))) 

मेरी .emacs में मैं निम्नलिखित समारोह इस मान प्राप्त है और एक virtualenv पथ प्रदान करने के लिए है

(add-hook 'python-mode-hook 'cr/python-mode-shell-setup) 

(defun cr/python-mode-shell-setup() 
    (message "virtualenv-name is %s" cr/virtualenv-name) 
    (let ((python-base (cr/virtualenv))) 
    (cond ((and (fboundp 'ipython-shell-hook) (file-executable-p (concat python-base "/bin/ipython"))) 
      (setq python-python-command (concat python-base "/bin/ipython")) 
      (setq py-python-command (concat python-base "/bin/ipython")) 
      (setq py-python-command-args '("-colors" "NoColor"))) 
      (t 
      (setq python-python-command (concat python-base "/bin/python")) 
      (setq py-python-command (concat python-base "/bin/python")) 
      (setq py-python-command-args nil))))) 

जब मैं एक नया अजगर फ़ाइल खोलते हैं, संदेशद्वारा लॉग:

अंत में, मेरी अजगर मोड हुक सूची में, मैं इस हुक समारोह है 210 इंगित करता है कि cr/virtualenv-namenil है। हालांकि, जब मैं सी-एच वी नाम करता हूं, तो मुझे इसके बजाय "सास" मिलता है।

स्पष्ट रूप से यहां एक लोड ऑर्डर समस्या है; क्या मेरे मोड हुक स्टेटमेंट्स निर्देशिका-स्थानीय चर के जवाब देने का कोई तरीका है?

उत्तर

12

ऐसा इसलिए होता है क्योंकि normal-mode(set-auto-mode) और (hack-local-variables) उस क्रम में कॉल करता है।

हालांकि hack-local-variables-hook स्थानीय चर के बाद चलाया जाता है संसाधित किया गया है, जो कुछ समाधान सक्षम बनाता है:

:

  1. पहले Emacs चलाने एक नया प्रत्येक प्रमुख मोड के लिए "स्थानीय चर हुक" बनाने के लिए है

    (add-hook 'hack-local-variables-hook 'run-local-vars-mode-hook) 
    (defun run-local-vars-mode-hook() 
        "Run a hook for the major-mode after the local variables have been processed." 
        (run-hooks (intern (concat (symbol-name major-mode) "-local-vars-hook")))) 
    
    (add-hook 'python-mode-local-vars-hook 'cr/python-mode-shell-setup) 
    

    (आपका मूल कार्य असंशोधित इस्तेमाल किया जा सकता, कि दृष्टिकोण के साथ।)

  2. एक दूसरा विकल्प वैकल्पिक 012 उपयोग करने के लिए हैadd-hook पर तर्क जो निर्दिष्ट फ़ंक्शन बफर-स्थानीय बनाता है। इस प्रकार इस दृष्टिकोण के साथ आप अपने हुक लिख सकते हैं:

    (add-hook 'python-mode-hook 'cr/python-mode-shell-setup) 
    
    (defun cr/python-mode-shell-setup() 
        (add-hook 'hack-local-variables-hook 
          (lambda() (message "virtualenv-name is %s" cr/virtualenv-name) 
           (let ((python-base (cr/virtualenv))) 
           (cond ((and (fboundp 'ipython-shell-hook) (file-executable-p (concat python-base "/bin/ipython"))) 
             (setq python-python-command (concat python-base "/bin/ipython")) 
             (setq py-python-command (concat python-base "/bin/ipython")) 
             (setq py-python-command-args '("-colors" "NoColor"))) 
             (t 
             (setq python-python-command (concat python-base "/bin/python")) 
             (setq py-python-command (concat python-base "/bin/python")) 
             (setq py-python-command-args nil))))) 
          nil t)) ; buffer-local hack-local-variables-hook 
    

    अर्थात python-mode-hook रन पहली और एकमात्र मौजूदा बफर के लिए hack-local-variables-hook साथ गुमनाम समारोह पंजीकृत करता है; और उस समारोह को स्थानीय चर के संसाधित होने के बाद बुलाया जाता है।

  3. लिंडडिंसर की टिप्पणी तीसरे दृष्टिकोण को संकेत देती है। यह लगभग दो के रूप में साफ नहीं है, लेकिन परवाह किए बिना दिलचस्प साबित हुआ। मैं (hack-local-variables) दो बार के नाम से जाना के कारण का विचार पसंद नहीं था, लेकिन मैं, देखना है कि अगर आप local-enable-local-variables बफर-स्थानीय स्तर पर निर्धारित करते हैं, यह (hack-local-variables) रोकता है कुछ भी करने से तो आप ऐसा कर सकता है:

    (defun cr/python-mode-shell-setup() 
        (report-errors "File local-variables error: %s" 
        (hack-local-variables))) 
        (set (make-local-variable 'local-enable-local-variables) nil) 
        (let ((python-base (cr/virtualenv))) 
        ...)) 
    

    जाहिर है कि निष्पादन के सामान्य अनुक्रम को थोड़ा सा संशोधित करता है, इसलिए दुष्प्रभाव संभव हो सकते हैं। मैं चिंतित था कि अगर एक ही प्रमुख मोड स्थानीय चर फ़ाइल फ़ाइल में सेट किया गया है, तो यह अनंत रिकर्सन का कारण बन सकता है, लेकिन यह वास्तव में एक समस्या नहीं प्रतीत होता है।

    स्थानीय चर हेडर टिप्पणियां (उदा। -*- mode: foo -*-) (set-auto-mode) द्वारा प्रबंधित की जाती हैं, इसलिए वे ठीक हैं; लेकिन mode: fooLocal Variables: टिप्पणी ऐसा लगता है कि यह एक मुद्दा होगा क्योंकि इसे (hack-local-variables) द्वारा संभाला जाता है, और इसलिए यदि मोड इस तरह से सेट किया गया है तो मैंने सोचा कि यह रिकर्सन का कारण बन जाएगा।

    प्रैक्टिस में मैं एक साधारण कार्य को 'मोड' के रूप में उपयोग करके समस्या को ट्रिगर करने में सक्षम था, जिसने अपने हुक चलाने की कोशिश करने से कुछ भी नहीं किया; हालांकि 'उचित' मोड के साथ परीक्षण ने समस्या का प्रदर्शन नहीं किया, इसलिए यह वास्तव में वास्तविकता में सुरक्षित है। मैंने इस पर आगे नहीं देखा (क्योंकि अन्य दो समाधान इस से अधिक स्वच्छ हैं), लेकिन मुझे लगता है कि देरी मोड हुक तंत्र शायद यह समझाएगा?

+0

शायद आप अपने हुक से (हैक-स्थानीय-चर) कॉल कर सकते हैं? – Lindydancer

+2

मेरी इच्छा है कि मैं इसे दो बार बढ़ा सकता हूं। –

संबंधित मुद्दे

 संबंधित मुद्दे