कैसे मैं एक Emacs पैकेज पैच करूँ?


16

मैं एक पैकेज में बदलाव करना चाहता हूं, इसका परीक्षण करूंगा और उम्मीद है कि बाद में एक पुल अनुरोध प्रस्तुत करूंगा। मैं इसे सुरक्षित और कुशल तरीके से कैसे करूं? प्रश्न बहुत व्यापक लग सकता है, मैं निम्नलिखित मुद्दों को कवर करने वाले उत्तर को स्वीकार करूंगा:

  1. मैं एक पैकेज की एक अलग शाखा स्थापित करने की उम्मीद करूंगा और जब यह आवश्यक हो तो पुन: स्थापन के साथ इसे और एक स्थिर पर स्थिर शाखा के बीच स्विच करने में सक्षम होगा, लेकिन package.elऐसा करने के लिए एक सीधा रास्ता प्रदान नहीं करता है। एमएसीएस-एसई पर यह उत्तर हमें सूचित करता है कि "यदि पैकेज की कई प्रतियां स्थापित की जाती हैं, तो पहले एक लोड होगी" इसलिए मुझे लगता है कि कोई मैन्युअल रूप से गड़बड़ी कर सकता है load-pathलेकिन यह मजबूत महसूस नहीं करता है। स्थापित किए गए लोगों के बीच पैकेज के एक विशिष्ट संस्करण का चयन करने का मानक तरीका क्या है?

  2. भले ही मैं Emacs को कई शाखाओं को उजागर करने का प्रबंधन करता हूं, महत्वपूर्ण बदलावों के लिए मुझे यह सुनिश्चित करने की आवश्यकता है कि अप्रकाशित शाखा "अनलोड" है और इसके साइड-इफेक्ट अलग-थलग हैं। क्या unload-featureयह ठीक से संभालता है या हो सकता है कि इसके पास कई प्रकार के पैकेज हैं जिनके बारे में मल्टी-वर्जन पैकेज के प्रत्येक परीक्षक को पता होना चाहिए?

  3. मैं स्थानीय संस्करण कैसे स्थापित और परीक्षण करूं? यह उत्तर इस बात पर निर्भर करता है कि पैकेज सरल है (= एक फ़ाइल) या बहुस्तरीय। EmacsWiki मल्टीफाइल पैकेज के बारे में कहता है: “ MELPA आपके लिए पैकेज बनाता है ”। मुझे संदेह है कि मुझे हर बार MELPA से बात करनी चाहिए (या होनी चाहिए), defunलेकिन मैं एक मल्टीफ़ाइल पैकेज में एक फॉर्म को बदल देता हूं लेकिन सवाल बना रहता है। कम से कम मुझे पैकेज प्रबंधक को स्थानीय संस्करण के बारे में बताने की आवश्यकता है, और यदि हां, तो मैं इसे कैसे करूं?

  4. मुझे संकुल के स्थानीय संस्करणों में कौन से नाम निर्दिष्ट करने चाहिए? मान लीजिए कि मैं एक साथ कई विशेषताओं या बग्स पर काम करना चाहता हूं, जिसका अर्थ है कई शाखाएँ। Emacs एक वर्णनात्मक तरीके से (लाइनों के साथ 20170117.666-somebugorfeature) नामों का नाम नहीं देगा । मुझे लगता है कि मैं अपने आप को पैकेज का नाम बदल सकता हूं, प्रति शाखा प्रत्यय, लेकिन फिर से, load-pathQ1 में मैन्युअल रूप से गड़बड़ी की तरह , यह एक बदसूरत हैक है, इसलिए मैं इसे कुछ के साथ आज़माने की कोशिश नहीं करूंगा जब तक कि यह एक व्यापक रूप से स्वीकृत अभ्यास न हो। ।

सवाल शायद भोले हैं, क्योंकि मैंने कभी भी एक पैच नहीं लिखा और न ही गिट या इसी तरह के vcs के साथ आवेदन किया। हालाँकि, बहुत से Emacs उपयोगकर्ताओं के लिए, Emacs पैकेज को पैच करना उनका पहला (या शायद केवल एक) सामाजिक प्रोग्रामिंग प्रयास हो सकता है, यही कारण है कि, मेरा मानना ​​है कि इस प्रश्न के उत्तर अभी भी मूल्यवान होंगे।

जवाबों:


7

पैकेज के विभिन्न संस्करणों को लोड करने के लिए थोड़ा अलग काम प्रवाह के साथ झंकार करने के लिए, यहां मैं जो कुछ भी करता हूं उसके कुछ रूपांतर हैं, जिनमें से दोनों load-pathको नियंत्रित करने के लिए मैं किस संस्करण का उपयोग कर रहा हूं (पैकेज का नाम बदलना एक बुरा विचार है) यदि निर्भरताएँ हैं)। मेरे पास "नाइस-पैकेज" का वर्तमान संस्करण है जो ~/.emacs.d/elpaप्रयोग में स्थापित है M-x package-install, और पैकेज रेपो क्लोन के ~/src/nice-packageसाथ है git clone ...

उपयोग-पैकेज के साथ

Init.el में, मेरे पास है

(use-package nice-package
  :load-path "~/src/nice-package"
  ...)

साथ :load-pathलाइन uncommented, इस पैकेज का Git संस्करण का उपयोग करेगा। इस लाइन को टिप्पणी करना, और emacs को पुनः लोड करना elpa संस्करण का उपयोग करता है।

उपयोग-पैकेज के बिना समान

Init.el में,

(add-to-list 'load-path "~/src/nice-package")
(require 'nice-package)
...

अब पहली पंक्ति के साथ एक ही टिप्पणी चाल है।

का उपयोग करते हुए emacs -L

यह एक ही विचार है, लेकिन load-pathकमांड लाइन से हेरफेर है । आप पैकेज के git संस्करण के साथ emacs का एक उदाहरण लोड कर सकते हैं

emacs -L ~/src/nice-package

जो सिर्फ लोड-पथ के सामने की ओर इस पथ को प्रस्तुत करता है। इस तरह, आप emacsएक अलग टर्मिनल से लॉन्च कर सकते हैं और पैकेज के साथ-साथ चलने वाले पैकेज के पुराने और नए संस्करण प्राप्त कर सकते हैं ।

विविध टिप्पणियाँ

  1. M-x eval-bufferआपके द्वारा बनाई गई नई परिभाषाओं को लोड करने के लिए पैकेज फ़ाइल को संपादित करने के बाद उपयोग करें ।
  2. संकलक क्या कहता है, M-x emacs-lisp-byte-compileयह जाँचना भी आसान है

मैं emacs -Lएक पैकेज के स्थानीय संस्करण को लोड करने के लिए दृष्टिकोण का उपयोग कर रहा हूं जो मैंने कास्क का उपयोग करके विश्व स्तर पर भी स्थापित किया है। एक बात जो मुझे खटकती थी, वह यह कि <package>-versionहमेशा विश्व स्तर पर स्थापित संस्करण को वापस लौटाया जाता है, तब भी जब मैं वास्तव में स्थानीय संशोधित संस्करण चला रहा था। यह पता चला है क्योंकि <package>-versionइस पैकेज के लिए संस्करण से मिलता है packages.el
ntc2

3

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

लेकिन अब, straight.elEmacs के लिए अगली पीढ़ी का पैकेज प्रबंधक है जो इस समस्या को यथासंभव व्यापक रूप से संबोधित करता है। डिस्क्लेमर: मैंने लिखा है straight.el!

बूटस्ट्रैप स्निपेट डालने के बाद , पैकेज स्थापित करना उतना ही सरल है जितना कि

(straight-use-package 'magit)

यह मैगिट के लिए गिट रिपॉजिटरी को क्लोन करेगा, अपनी फ़ाइलों को एक अलग निर्देशिका, बाइट-कंपाइल में उत्पन्न करके और ऑटोलोड्स का मूल्यांकन करके और load-pathसही ढंग से कॉन्फ़िगर करके पैकेज का निर्माण करेगा । बेशक, यदि पैकेज पहले से ही क्लोन किया गया है और बनाया गया है, तो कुछ भी नहीं होता है, और आपके init समय में नुकसान नहीं होता है।

आप मैगिट में परिवर्तन कैसे करते हैं? यह तुच्छ है! बस स्रोत कोड पर जाने के लिए उपयोग करें M-x find-functionया M-x find-libraryदूर करें, और हैक करें! आप उन्हें लाइव परीक्षण करने के लिए अपने परिवर्तनों का मूल्यांकन कर सकते हैं, जैसा कि Emacs Lisp विकास के लिए सामान्य अभ्यास है, और जब आप Emacs को पुनरारंभ करते हैं, तो पैकेज स्वचालित रूप से फिर से बनाया जाएगा, फिर से संकलित किया जाएगा, और इसी तरह। यह पूरी तरह से स्वचालित और फुलप्रूफ है।

जब आप अपने बदलावों से संतुष्ट हो जाते हैं, तो बस एक प्रतिबद्धता, धक्का और एक अनुरोध करें। आपके पास अपने स्थानीय पैकेजों पर कुल नियंत्रण है। लेकिन आपका कॉन्फ़िगरेशन अभी भी 100% प्रतिलिपि प्रस्तुत करने योग्य हो सकता है क्योंकि आप लॉकफ़ाइल straight.elबनाने के लिए कह सकते हैं जो आपके सभी पैकेजों के गिट संशोधनों को बचाता है, जिसमें straight.elस्वयं, एमईएलपीए और इसी तरह शामिल हैं।

straight.elMELPA, GNU ELPA, या EmacsMirror से कोई भी पैकेज स्थापित कर सकते हैं। लेकिन इसमें एक अत्यधिक लचीला नुस्खा डीएसएल भी है जो आपको कहीं से भी स्थापित करने की अनुमति देता है, साथ ही साथ यह भी अनुकूलित करता है कि पैकेज कैसे बनाया गया है। यहाँ एक उदाहरण है जो कुछ विकल्पों को दर्शाता है:

(straight-use-package
 '(magit :type git 
         :files ("lisp/magit*.el" "lisp/git-rebase.el"
                 "Documentation/magit.texi" "Documentation/AUTHORS.md"
                 "COPYING" (:exclude "lisp/magit-popup.el"))
         :host github :repo "raxod502/magit"
         :upstream (:host github :repo "magit/magit")))

straight.elहास्यास्पद व्यापक प्रलेखन है। GitHub पर इसके बारे में सब पढ़ें ।


2

ये सभी अच्छे प्रश्न हैं!

Emacs एक मेमोरी-इमेज मॉडल पर काम करता है, जहाँ नया कोड लोड करने से रनिंग इंस्टेंस की मेमोरी इमेज बदल जाती है। नए कार्यों और चर को परिभाषित करना आसानी से पूर्ववत है, यदि आप उनमें से एक सूची रखते हैं, लेकिन बहुत सारे दुष्प्रभाव हैं एक मॉड्यूल हो सकता है कि आप पूर्ववत करना चाहते हैं। ऐसा लगता unload-featureहै कि हालांकि यह एक बहुत अच्छा जाना है।

मुझे लगता है कि आप जो करना चाहते हैं वह लाइव कोडिंग और कभी-कभार Emacs का संयोजन है, उस मॉड्यूल को लोड करना जिसे आप अपनी शाखा से काम कर रहे हैं बजाय इसके कि वह कहाँ से स्थापित है। यदि आप इन शाखाओं के बहुत से अंत करते हैं, तो आप एक शेल स्क्रिप्ट चाहते हैं जो load-pathउस क्षण के लिए सही के साथ emacs लॉन्च करता है जिस पर आप काम कर रहे हैं। किसी भी स्थिति में मैं पैकेज का नाम नहीं बदलूंगा; मुझे लगता है कि emacs तब उन दोनों को लोड कर सकता है और भी अधिक भ्रामक होगा।

जैसा कि आप अपने पैच विकसित करते हैं, तो आप केवल उन कार्यों को पुनर्परिभाषित कर सकते हैं जिन्हें आप अपने लाइव Emacs सत्र में सही बदल रहे हैं। यह आपको इमैक छोड़ने के बिना, नई परिभाषाओं का तुरंत परीक्षण करने देता है। विशेष रूप से, जैसा कि आप अपने वर्तमान Emacs सत्र में वर्तमान फ़ंक्शन का मूल्यांकन करने के लिए C-M-x( eval-defun) का उपयोग कर सकते हैं एक अनिवार्य फ़ाइल को संपादित करते हैं। फिर आप यह सुनिश्चित करने के लिए कॉल कर सकते हैं कि यह काम करता है। यदि आप कुछ ऐसा बदल रहे हैं जो Emacs स्टार्टअप पर होता है, तो आपको इसकी जांच करने के लिए Emacs को शुरू और बंद करना होगा; आप एक अलग Emacs प्रक्रिया शुरू और रोक कर ऐसा कर सकते हैं ताकि आपका संपादन सत्र बाधित न हो।


2

मुझे नहीं लगता कि इसके बारे में अभी तक कोई अच्छा जवाब मिला है (मुझे उम्मीद है कि आप पीपा के साथ एक आंशिक समाधान प्राप्त कर सकते हैं, यद्यपि मैं आपको इसका उपयोग करने के लिए एक अच्छा जवाब देने के लिए पर्याप्त परिचित नहीं हूं; उम्मीद है कि कोई और होगा), लेकिन यहां; मैं क्या करता हूं (स्थानीय परिवर्तन किए बिना मैं शायद ही कभी एक एलिस्प पैकेज का उपयोग करता हूं, इसलिए यह वास्तव में मेरा "सामान्य" तरीका है):

  • cd ~/src; git clone ..../elpa.git
  • प्रत्येक पैकेज के लिए cd ~/src/elisp; git clone ....thepackage.git
  • cd ~/src/elpa/packages; ln -s ~/src/elisp/* .
  • cd ~/src/elpa; make
  • आपके ~/.emacsऐड में

    (eval-after-load 'package
     '(add-to-list 'package-directory-list
                   "~/src/elpa/packages"))
    

इस तरह, सभी पैकेज "गेट से सीधे" स्थापित होते हैं, एक सरल cd ~/src/elpa; makeउन लोगों को फिर से स्थापित करेगा जो इसकी आवश्यकता है, और C-h o thepackage-functionएक स्रोत फ़ाइल पर कूदेंगे जो कि गिट के तहत है।

"इसे और एक शाखा पर स्थिर शाखा के बीच स्विच करने के लिए", आपको इसकी आवश्यकता होगी git checkout <branch>; cd ~/src/elpa; make; और यदि आप चाहते हैं कि यह Emacs सत्र चलाने को प्रभावित करे तो यह अधिक काम लेगा। मैं आमतौर पर unload-featureअसाधारण स्थितियों को छोड़कर उपयोग नहीं करने की सलाह देता हूं (यह एक अच्छी सुविधा है, लेकिन वर्तमान में यह पर्याप्त विश्वसनीय नहीं है)।

यह आपकी कई आवश्यकताओं को भी पूरा नहीं करता है। और इसके कुछ अतिरिक्त डाउनसाइड्स हैं, ज्यादातर यह तथ्य कि कई पैकेजों की गिट क्लोन elpa.it के मेकफाइल द्वारा अपेक्षित लेआउट और सामग्री से मेल नहीं खाती है, इसलिए आपको उन पैकेजों को टटोलना शुरू करना होगा (आमतौर पर उन चीजों के साथ जो करना है <pkg>-pkg.el, क्योंकि elpa.git की मेकफाइल ने अपेक्षा की है कि इस फ़ाइल को बनाने के <pkg>.elबजाय इसे प्रदान किया जाए, लेकिन अधिक समस्याग्रस्त रूप से, संकलन अलग तरीके से किया जाता है, इसलिए कभी-कभी आपको requireएस के साथ खेलने की आवश्यकता होती है )।

ओह और निश्चित रूप से, इसका मतलब है कि आप उन पैकेजों को हाथ से स्थापित कर रहे हैं, इसलिए आपको निर्भरता पर ध्यान देना होगा। यह सेटअप package-install, tho द्वारा स्थापित अन्य पैकेजों के साथ ठीक से इंटरैक्ट करता है , इसलिए यह इतना भयानक नहीं है।


2

इस प्रश्न के अन्य उत्तर , मेरे अन्य उत्तर सहित , इसके कोड में परिवर्तन करके Emacs पैकेज को पैच करने की बात करते हैं। लेकिन Google के माध्यम से इस प्रश्न को खोजने वाले लोग "पैच एमाक्स पैकेज" कहने पर कुछ और सोच सकते हैं - अर्थात्, अपने स्रोत कोड को संशोधित किए बिना अपने व्यवहार को ओवरराइड कर सकते हैं।

आक्रामकता के बढ़ते क्रम में ऐसा करने के लिए तंत्र शामिल हैं:

  • हुक का उपयोग करने के लिए फ़ंक्शन जोड़ना , या डायनामिक वैरिएबल का उपयोग करके बाइंड करनाlet
  • शक्तिशाली सलाह प्रणाली
  • केवल उस फ़ंक्शन को ओवरराइड करना जो आप संशोधित करना चाहते हैं

पहले दो विकल्पों की शक्ति के बावजूद, मैंने अपने आप को तीसरा रास्ता बहुत बार लिया, क्योंकि कभी-कभी कोई और रास्ता नहीं होता है। लेकिन फिर सवाल यह है कि अगर मूल फ़ंक्शन की परिभाषा बदल जाए तो क्या होगा? आपको यह जानने का कोई तरीका नहीं होगा कि आपको उस परिभाषा के संस्करण को अपडेट करने की आवश्यकता है जिसे आपने अपनी इन-फाइल में कॉपी और पेस्ट किया है!

क्योंकि मैं पैचिंग चीजों से ग्रस्त हूं, मैंने पैकेज लिखा el-patch, जो इस समस्या को यथासंभव व्यापक रूप से हल करता है। विचार यह है कि आप एस-एक्सप्रेशन आधारित अपनी इन-फाइल में अंतर करते हैं, जो मूल फ़ंक्शन परिभाषा और उस पर आपके परिवर्तनों दोनों का वर्णन करता है। यह आपके पैच को अधिक पठनीय बनाता है, और el-patchबाद में यह पुष्टि करने की भी अनुमति देता है कि जब आपने अपना पैच बनाया था तब से मूल फ़ंक्शन परिभाषा को अपडेट किया गया है या नहीं। (यदि ऐसा है, तो यह आपको एडिफ के माध्यम से बदलाव दिखाएगा!) प्रलेखन से उद्धरण:

company-statisticsपैकेज में परिभाषित निम्नलिखित फ़ंक्शन पर विचार करें :

(defun company-statistics--load ()
  "Restore statistics."
  (load company-statistics-file 'noerror nil 'nosuffix))

मान लीजिए कि हम उस आंकड़े की फ़ाइल को लोड करते समय लॉग होने वाले संदेश को दबाने के nilलिए 'nomessage, तीसरे तर्क को बदलना चाहते हैं company-statistics। हम निम्नलिखित कोड को अपने पास रखकर ऐसा कर सकते हैं init.el:

(el-patch-defun company-statistics--load ()
  "Restore statistics."
  (load company-statistics-file 'noerror
        (el-patch-swap nil 'nomessage)
        'nosuffix))

बस एक नो-ऑप पैच el-patch-defunको defunपरिभाषित करने के बजाय कॉल करना : अर्थात, इसका कोई प्रभाव नहीं है (ठीक है, काफी नहीं - बाद में देखें )। हालांकि, पैच निर्देशों को शामिल करके , आप फ़ंक्शन के संशोधित संस्करण को मूल से अलग बना सकते हैं।

इस मामले में, हम el-patch-swapनिर्देश का उपयोग करते हैं । el-patch-swapफार्म के साथ बदल दिया है nilमूल परिभाषा (यह है कि, उस संस्करण में "आधिकारिक" परिभाषा के खिलाफ तुलना की जाती है company-statistics.el), और साथ 'nomessageसंशोधित परिभाषा (यह है कि, संस्करण है कि वास्तव में अपने init-फ़ाइल में मूल्यांकन किया जाता है)।


0

जब आप बहुत बदलाव करते हैं, तो मुझे लगता है कि आपको रेडॉन रोसबोरोstraight.el का जवाब देखना चाहिए ।

यदि आप केवल एक बदलाव करना चाहते हैं, तो चलो एक परियोजना को कहते हैं fork-mode, निम्नलिखित कदम उठाएँ:

  • गिट को स्टोर करने के लिए एक निर्देशिका बनाएं mkdir ~/.emacs.d/lisp-gits
  • जिस परियोजना को आप बदलना चाहते हैं, उसका एक कांटा बनाएं, पर कहें https://github.com/user/fork-mode
  • अपने कांटे को क्लोन करें cd ~/.emacs.d/lisp-gits && git clone git@github.com:user/fork-mode.git

निम्नलिखित कोड अपने में लिखें .emacs

(if (file-exists-p "~/.emacs.d/lisp-gits/fork-mode")
    (use-package fork-mode :load-path "~/.emacs.d/lisp-gits/fork-mode")
  (use-package fork-mode :ensure t))

(use-package fork-mode
  :config
  (setq fork-mode-setting t)
  :hook
  ((fork-mode . (lambda () (message "Inside hook"))))

अब आप एमएसीएस मोड का उपयोग कर सकते हैं, C-h fउन फ़ंक्शन का उपयोग करने के लिए जिन्हें आप बदलना चाहते हैं। आप देखेंगे कि जब पैकेज को लिस्प-गिट्स में स्थापित किया जाता है, तो आप वहां कूदेंगे। परिवर्तन करने / धकेलने के लिए मैगिट या अन्य git कमांड का उपयोग करें और फिर अपने पुल अनुरोध भेजने के लिए github का उपयोग करें।

एक बार जब आपके पुल अनुरोध स्वीकार कर लिए जाते हैं तो आप प्रोजेक्ट को केवल हटा सकते हैं ~/.emacs.d/lisp-gitsऔर पैकेज मैनेजर को अपना काम करने दे सकते हैं।

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