प्रोज-मोड से मुझे कैसे विरासत में मिला, जबकि अभी भी पुराने इमैकेन का समर्थन है?


10

मैं एक प्रोग्रामिंग भाषा के लिए एक प्रमुख विधा लिख ​​रहा हूं, लेकिन मैं पुराने Emacs संस्करणों का समर्थन करना चाहता हूं। prog-modeअपेक्षाकृत नया है। prog-modeअगर यह परिभाषित किया गया है, तो मैं इनहेरिट करना चाहता हूं , लेकिन फिर भी कुछ समझदारी से करें।

सबसे अच्छा तरीका क्या है? क्या मुझे defalias prog-modeपुराने Emacsen पर होना चाहिए , या यदि वे एक ही काम करते हैं तो क्या अन्य तरीकों से हस्तक्षेप करना चाहिए ?


मैं बस Emacs <24 के लिए समर्थन छोड़ने की सलाह देता हूं। मेरी राय में यह अब और प्रयास के लायक नहीं है, और आपको इससे अधिक महत्वपूर्ण सुविधाओं को माफ करना होगा prog-mode। विशेष रूप से, आप शाब्दिक बंधन की कमी से पीड़ित होंगे।
चंद्र

मैं जूलिया-मोड में योगदान कर रहा हूं, और कुछ कोर टीम पुराने Emacsen का उपयोग करती है और पसंद करेगी कि हमने इसका समर्थन किया।
विल्फ्रेड ह्यूजेस

1
@lunaryorn Emacs 24 अभी भी बहुत नया है। एमएसीएस 23 कई ओएस पर वर्तमान संस्करण है। Emacs 22 अभी भी कुछ पर चालू है। हर कोई अपने सॉफ्टवेयर को पागलों की तरह अपग्रेड नहीं करता है। 23 Emacs के लिए समर्थन छोड़ने से आप उन कुछ उपयोगकर्ताओं तक सीमित हो जाएंगे जो खून बह रहा है।
गिल्स एसओ- बुराई पर रोक '23

1
पुराने Emacs संस्करणों का उपयोग करने के कई कारण हैं। उदाहरण के लिए, विंडोज पर, Emacs 23 वास्तव में सुस्त हो गया है, इसलिए मैंने वहां Emacs 22 से चिपके रहने का विकल्प चुना है।

@Gilles मुझे संदेह है कि यह सिर्फ "कुछ उपयोगकर्ता" हैं। फ्लाइचेक ने पहले स्थान पर 23 Emacs का समर्थन नहीं किया, और फिर भी MELPA पर सबसे लोकप्रिय पैकेजों में से एक बन गया ...
lunaryorn

जवाबों:


11

एक अतिरिक्त टॉप-लेवल सिंबल बाइंडिंग की कीमत पर, एक बहुत साफ समाधान है जो define-derived-modeफॉर्म को दोहराने से बचता है :

(defalias 'my-fancy-parent-mode
  (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))

(define-derived-mode my-fancy-mode my-fancy-parent-mode
   ...)

किसी भी Emacs> = 23 में ठीक काम करता है। मैं haml-modeIIRC के साथ कुछ साल पहले आया था, और लगता है कि यह वहाँ से कई अन्य प्रमुख तरीकों में फैल गया है। मुख्य बात यह है कि define-derived-modeमैक्रो मूल मोड प्रतीक के साथ करता है जो कोड उत्पन्न करता है जो इसके फ़ंक्शन को कॉल करता है: इस अर्थ में, defaliasनए चर को अलियास किए गए फ़ंक्शन के बराबर बनाता है।

एक चेतावनी यह है कि यह भ्रमित कर सकता है derived-mode-p, इसलिए कोड जो यह देखने के लिए जाँच करता है कि क्या आपका मोड prog-modeठीक से काम नहीं करता है। व्यवहार में मुझे कोई समस्या नहीं हुई है: ऐसे कोड को हुक करने के लिए यह सामान्य है prog-mode-hook, जो अभी भी चलता है।

(जैसा कि जॉर्गेन टिप्पणियों में बताते हैं, संपत्ति को मूल मोड प्रतीक से define-derived-modeभी उपयोग करते mode-classहैं, और defaliasइसे कॉपी नहीं करेंगे। लेखन के समय, यह संपत्ति केवल उपयोग के लिए लगती हैspecial-mode ।)

अद्यतन: इन दिनों मैं बस सुझाव दूंगा कि कम से कम Emacs 24 की आवश्यकता है, क्योंकि पुराने संस्करण लंबे अप्रचलित हैं।


2
अच्छा समाधान! बस एक चेतावनी: यह काम करता है prog-mode, लेकिन हर मोड के लिए काम नहीं करेगा। प्रतीक संपत्ति को चाइल्ड मोड में define-derived-modeकॉपी करता mode-classहै। defaliasहोगा नहीं इस प्रॉपर्टी स्थानांतरित करें। यदि mode-classआपके उपयोग के मामले में प्रासंगिक है, तो आपको इसे मैन्युअल रूप से कॉपी / सेट करने की आवश्यकता है।
जोर्गेन शेफर

जोर्गेन को पकड़ने के लिए धन्यवाद, मुझे चारों ओर खुदाई करनी होगी और अधिक जानना होगा कि mode-classसंपत्ति क्या दर्शाती है।
पवित्रता

3

tl; dr: उपयोग करें ifऔर अपने स्वयं के init फ़ंक्शन:

(if (fboundp 'prog-mode)
    (define-derived-mode your-cool-mode prog-mode "Cool"
      "Docstring"
      (your-cool--init))
  (define-derived-mode your-cool-mode nil "Cool"
    "Docstring"
    (your-cool--init)))

फिर सभी मोड का प्रारंभ करें your-cool-init

लंबी व्याख्या:

समस्या यह है कि एक व्युत्पन्न प्रमुख मोड लिखने का आधिकारिक तरीका define-derived-modeमैक्रो का उपयोग करना है :

(define-derived-mode your-cool-mode prog-mode ...)

पुराने Emacsen (पूर्व -24) पर, यह टूट जाता है जब prog-mode। और आप (if (fboundp 'prog-mode) ...)वहाँ उपयोग नहीं कर सकते क्योंकि मैक्रो को शाब्दिक प्रतीक की उम्मीद है, और विस्तार में आपके लिए इसे उद्धृत करेगा।

define-derived-modeकई तरीकों से माता-पिता का उपयोग करता है। आप उन सभी का उपयोग करने के लिए अपने स्वयं के मोड परिभाषा में कॉपी करने की आवश्यकता होगी, और यह दोनों कठिन और त्रुटि प्रवण है।

इसलिए एकमात्र तरीका दो अलग-अलग define-derived-modeकथनों का उपयोग करना prog-modeहै , जो इस बात पर निर्भर करता है कि मौजूद है या नहीं। जो आपको अपने इनिशियलाइज़ेशन कोड को दो बार लिखने की समस्या के साथ छोड़ देता है। जो निश्चित रूप से बुरा है, इसलिए आप इसे ऊपर बताए गए अनुसार अपने स्वयं के कार्य में निकाल सकते हैं।

(सबसे अच्छा समाधान निश्चित रूप से 23.x के लिए समर्थन छोड़ना और शाब्दिक स्कोपिंग का उपयोग करना है। लेकिन मुझे लगता है कि आपने पहले ही विचार किया था और उस विकल्प को छोड़ दिया था। :-))


prog-modeपुराने Emacsen में निकटतम समतुल्य क्या है ? यह समझ में आता है text-modeया fundamental-modeअगर prog-modeउपलब्ध नहीं है?
विल्फ्रेड ह्यूजेस

@ जोर्जेन या हम fboundpकेवल define-derived-modeबयान के साथ पहले का उपयोग करके एक मध्यवर्ती मोड प्राप्त कर सकते हैं ? फिर पूरी परिभाषा के साथ वास्तविक मोड को उस मध्यवर्ती मोड से प्राप्त किया जा सकता है? इस तरह पूरे मोड को दो बार परिभाषित करने की आवश्यकता नहीं है।
कौशल मोदी

1
@IlfredHughes, कोई नहीं है। से fundamental-modeव्युत्पन्न करना nil(और वास्तव में, से define-derived-modeबदलता fundamental-modeहै nil) के बराबर है , जबकि text-modeउचित नहीं है, क्योंकि प्रोग्राम कोड पाठ नहीं है। अधिकांश डिफ़ॉल्ट सेटिंग्स text-modeटिप्पणियों के बाहर प्रोग्रामिंग मोड में समझ में नहीं आती हैं। यही कारण है कि prog-modeEmacs 24 में पेश किया गया था।
Jorgen Schäfer

@kaushalmodi, आप एक मध्यवर्ती मोड प्राप्त कर सकते हैं, लेकिन इसके लिए अभी भी एक मोड में दो define-derived-modeपरिभाषाओं की आवश्यकता होगी if, केवल अंतिम मोड के बजाय मध्यवर्ती मोड के लिए। आप अंतिम मोड के लिए defuninit फ़ंक्शन के लिए प्रतिस्थापित कर रहे होंगे define-derived-mode। मुझे नहीं लगता कि यह विशेष रूप से बेहतर है। आप prog-modeस्वयं को परिभाषित भी कर सकते हैं , जैसा कि मूल प्रश्न से पता चलता है, लेकिन यह अन्य मोड को आसानी से भ्रमित कर सकता है जो fboundpउस मोड की उपस्थिति की जांच करने के लिए भरोसा करते हैं ।
जोर्गन शेफर

मैं नहीं मानता कि दो अलग-अलग define-derived-modeकथन आवश्यक हैं। कुछ साल पहले मैं उस समाधान के साथ आया हूं जिसे मैंने एक अलग उत्तर के रूप में पोस्ट किया है, और यह दोनों एमएसीएस 23 और 24 में ठीक काम करता है। कोड जैसे कि यह कई लोकप्रिय प्रमुख मोड में उपयोग किया जाता है।
14


0

आप एक रैपर मैक्रो को परिभाषित कर सकते हैं जो define-derived-modeइसके तर्कों का मूल्यांकन करता है।

(defmacro define-derived-mode* (child parent name &optional docstring &rest body)
  (macroexpand `(define-derived-mode ,(eval child) ,(eval parent) ,(eval name)
                                     ,(eval docstring) . ,body)))
(define-derived-mode* 'toy-mode
  (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode)
  "Toy"
  "Major mode for my favorite toy language"
  (toy-mode-setup))

(चेतावनी: केवल न्यूनतम परीक्षण किया गया।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.