Emacs paketini nasıl eklerim?


16

Bir paketi değiştirmek, test etmek ve umarım daha sonra bir çekme isteği göndermek istiyorum. Nasıl güvenli ve verimli bir şekilde yapabilirim? Soru çok geniş hissedebilir, aşağıdaki sorunları kapsayan cevabı kabul edeceğim:

  1. Bir paketin ayrı bir dalını kurmayı ve gerektiğinde otomatik olarak yapılan yeniden derleme ile bir kapris üzerinde istikrarlı dal arasında geçiş yapabilmeyi beklerdim, ancak package.elbunu yapmak için basit bir yol sunmuyor gibi görünüyor. Emacs-SE'deki bu cevap , bize “Bir paketin birden fazla kopyası yüklüyse, o zaman ilk paket yüklenir” diye bildirir, bu yüzden birinin elle karışabileceğini load-pathama bu sağlam hissetmeyeceğini tahmin ediyorum . Kurulu olanlar arasından paketin belirli bir sürümünü seçmenin standart yolu nedir?

  2. Birkaç şubeyi Emacs'a göstermeyi başarabilsem bile, önemli değişiklikler için, işlenmemiş dalın “boşaltıldığından” ve yan etkilerinin izole edildiğinden emin olmalıyım. unload-featureBunu düzgün bir şekilde ele alıyor mu, yoksa çok sürümlü paketlerin her test edicisinin bilmesi gereken kendine özgü ifadeleri vardır?

  3. Yerel sürümü nasıl yükler ve test ederim? Yanıt, paketin basit (= bir dosya) veya çok dosyalı olmasına bağlı gibi görünüyor. EmacsWiki çok dosyalı paketler hakkında şunları söylüyor: “ MELPA sizin için paketler oluşturur ”. Çok dosyalı defunbir paketteki bir formu her değiştirdiğimde MELPA ile konuşmam gerektiğinden (veya yapmam gerektiğinden) şüpheliyim ama soru hala devam ediyor. En azından paket yöneticisine yerel sürümden bahsetmem gerekiyor ve eğer öyleyse, bunu nasıl yapabilirim?

  4. Paketlerin yerel sürümlerine hangi adları atamalıyım? Aynı anda birden fazla özellik veya hata üzerinde çalışmak istediğimi varsayalım, bu da birkaç şubeye sahip olmak anlamına geliyor. Emacs, sürümleri açıklayıcı bir şekilde (satırları boyunca 20170117.666-somebugorfeature) adlandırmaya izin vermez . Sanırım paketin kendisini, şube başına bir son eki yeniden adlandırabilirim, ancak yine, load-pathQ1'de elle karışıklık yapmak gibi , bu çirkin bir hack, bu yüzden yaygın olarak kabul edilen bir uygulama olmadığı sürece yukarı doğru göndermek istediğim bir şeyle denemeyeceğim .

Soruları muhtemelen naif, çünkü hiç git ya da benzer vcs ile bir yama yazmadım. Ancak, çok sayıda Emacs kullanıcısı için, bir Emacs paketini yamalamak ilk sosyal programlama çabası olabilir (ya da belki de tek), bu yüzden bu sorunun cevaplarının hala değerli olacağına inanıyorum.

Yanıtlar:


7

Paketlerin farklı sürümlerini yüklemek için biraz farklı bir iş akışı ile uğraşmak için, yaptığımın birkaç varyasyonu var, her ikisi de load-pathhangi sürümü kullandığımı kontrol etmek için kullanıyor (paketin adını değiştirmek kötü bir fikirdir bağımlılıklar varsa). ~/.emacs.d/elpaKullanırken yüklü "nice-package" mevcut sürümü var M-x package-installve paket repo klon ~/src/nice-packageile git clone ....

Kullanım paketi ile

İnit.el içinde var

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

İle :load-pathhat uncommented, bu paketin git sürümünü kullanacaktır. Bu satırı yorumlamak ve emac'leri yeniden yüklemek, elpa sürümünü kullanır.

Kullanım paketi olmadan benzer

İnit.el içinde,

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

Şimdi ilk satırda aynı yorum hilesini yap

kullanma emacs -L

Bu aynı fikirdir, ancak load-pathkomut satırından manipüle edilir. Paketin git sürümü ile emacs örneği yükleyebilirsiniz.

emacs -L ~/src/nice-package

yük yolunun önüne bu yolu ekler. Bu şekilde, emacsfarklı bir terminalden başlatabilir ve paketin eski ve yeni sürümlerini yan yana çalıştırabilirsiniz.

Çeşitli yorumlar

  1. M-x eval-bufferOluşturduğunuz yeni tanımları yüklemek için bir paket dosyasını düzenledikten sonra kullanın .
  2. Derleyicinin söylediklerini kontrol etmek M-x emacs-lisp-byte-compilede kullanışlı

emacs -LCask kullanarak global olarak yüklediğim bir paketin yerel bir sürümünü yüklemek için yaklaşımı kullanıyorum. Beni atmış olan bir şey <package>-version, aslında yerel olarak değiştirilmiş sürümü çalıştırırken bile , çalışmanın her zaman global olarak yüklenmiş sürümü döndürmesiydi. Bunun nedeni, <package>-versionbu paket için sürümü almak olduğu için oldu packages.el.
ntc2

3

İyi soru! Cevap, şimdiye kadar iyi bir yanıtın bulunmamasıydı, çünkü mevcut paket yöneticilerinin hiçbiri bu kullanım durumu için tasarlanmadı ( Borg hariç , ancak Borg bağımlılık yönetimi gibi diğer yaygın paket yönetimi işlemlerini gerçekleştirmeye çalışmaz) .

Ancak şimdi, straight.elEmacs için bu sorunu olabildiğince kapsamlı bir şekilde ele alan yeni nesil bir paket yöneticisi var. Feragatname: Yazdım straight.el!

Bootstrap snippet'ini ekledikten sonra , bir paketi yüklemek kadar basit

(straight-use-package 'magit)

Bu, Magit için Git deposunu klonlar, dosyalarını ayrı bir dizine bağlayarak paketi oluşturur, bayt-derler, otomatik yükler oluşturur ve değerlendirir ve load-pathdoğru yapılandırır . Tabii ki, eğer paket zaten klonlanmış ve inşa edilmişse, hiçbir şey olmaz ve init zamanınız acı çekmez.

Magit'te nasıl değişiklik yaparsınız? Önemsiz! Sadece kaynak koduna atlamak için M-x find-functionveya M-x find-librarytuşlarını kullanın ve kesmek! Değişikliklerinizi canlı olarak test etmek için değerlendirebilirsiniz, ayrıca Emacs Lisp geliştirme için genel bir uygulamadır ve Emacs'ı yeniden başlattığınızda, paket otomatik olarak yeniden oluşturulacak, yeniden derlenecek vb. Tamamen otomatik ve kusursuz.

Değişikliklerinizden memnun olduğunuzda, taahhütte bulunun, itin ve bir çekme isteği yapın. Yerel paketleriniz üzerinde tam kontrole sahipsiniz. Ancak yapılandırmanız yine de% 100 tekrarlanabilir olabilir, çünkü kendisi, MELPA vb. Dahil straight.elolmak üzere tüm paketlerin Git revizyonlarını kaydeden bir kilit straight.eldosyası isteyebilirsiniz.

straight.elMELPA, GNU ELPA veya EmacsMirror'dan herhangi bir paket yükleyebilir. Ancak, her yerden yüklemenizi ve paketin nasıl inşa edildiğini özelleştirmenizi sağlayan son derece esnek bir tarif DSL'sine de sahiptir. İşte bazı seçenekleri gösteren bir örnek:

(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.elgülünç derecede kapsamlı belgelere sahiptir. Bununla ilgili her şeyi GitHub'da okuyun .


2

Bunların hepsi güzel sorular!

Emacs, yeni kodun yüklenmesinin çalışan örneğin bellek görüntüsünü değiştirdiği bir bellek görüntüsü modelinde çalışır. Yeni işlevler ve değişkenler tanımlamak, bunların bir listesini tutarsanız kolayca geri alınır, ancak bir modülün geri almak isteyebileceğiniz birçok yan etkisi vardır. Yine de unload-featureoldukça iyi bir gitmek yapar gibi görünüyor .

Yapmak isteyeceğiniz şey, canlı kodlama ve bazen Emacs'ı yeniden başlatmak, üzerinde çalıştığınız modülü kurulu olduğu yerden değil şubenizden yüklemek. Bu dalların çoğuyla sonuçlanırsanız load-path, şu anda üzerinde çalıştığınız için doğru emacs başlatan bir kabuk komut dosyası isteyebilirsiniz . Her durumda paketi yeniden adlandırmazdım; Bence emacs her ikisini de yükleyebilir çünkü bu daha da kafa karıştırıcı olurdu.

Yamalarınızı geliştirirken, canlı Emacs oturumunuzda değiştirdiğiniz işlevleri yeniden tanımlayarak başlayabilirsiniz. Bu, Emacs'tan çıkmadan yeni tanımları hemen test etmenizi sağlar. Özellikle, bir elisp dosyasını düzenlerken , geçerli Emacs oturumunuzdaki geçerli işlevi değerlendirmek için C-M-x( eval-defun) kullanabilirsiniz . Daha sonra çalıştığından emin olmak için arayabilirsiniz. Emacs başlangıcında olan bir şeyi değiştiriyorsanız, muhtemelen test etmek için Emacs'ı başlatmanız ve durdurmanız gerekir; düzenleme oturumunuzun kesintiye uğramaması için ayrı bir Emacs işlemini başlatarak ve durdurarak bunu yapabilirsiniz.


2

Henüz buna iyi bir cevap olduğunu düşünmüyorum (Cask ile kısmi bir çözüm elde edebileceğinizi umuyorum, tho size bunu kullanarak iyi bir cevap vermek için yeterli tanıma sahip değilim; umarım başka biri olur), ama işte burada ne yaptığımı (nadiren bir Elisp paketini yerel değişiklikler yapmadan kullanıyorum, bu yüzden gerçekten "normal" yolum):

  • cd ~/src; git clone ..../elpa.git
  • her paket için cd ~/src/elisp; git clone ....thepackage.git
  • cd ~/src/elpa/packages; ln -s ~/src/elisp/* .
  • cd ~/src/elpa; make
  • senin içinde ~/.emacseklenti

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

Bu şekilde, tüm paketler "doğrudan Git'ten" yüklenir, basit bir paket cd ~/src/elpa; makeihtiyacı olanları yeniden derler ve C-h o thepackage-functionGit altındaki bir kaynak dosyaya atlar.

"Bir kapris üzerinde istikrarlı dal arasında geçiş yapmak" için git checkout <branch>; cd ~/src/elpa; make; ve çalışan Emacs oturumlarını etkilemesini istiyorsanız daha fazla iş gerekir. Genellikle unload-featureistisnai durumlar dışında kullanmamanızı tavsiye ederim (iyi bir özellik, ancak şu anda yeterince güvenilir değil).

Ayrıca gereksinimlerinizin çoğunu karşılamıyor. Ve bazı ekstra dezavantajları var, çoğunlukla birçok paketin Git klonunun elpa.git'in makamının beklediği düzen ve içerikle tam olarak eşleşmemesi, bu paketleri değiştirerek başlamanız gerekecek (genellikle bununla ilgili şeyler) <pkg>-pkg.el, elpa.git'in makefile dosyası sağlanmak <pkg>.elyerine bu dosyayı oluşturmayı beklediğinden , ancak daha sorunlu bir şekilde derleme farklı şekilde gerçekleştirilir, bu nedenle bazen requires ile oynamanız gerekir ).

Tabii ki, bu temel olarak bu paketleri elle kurduğunuz anlamına gelir, bu nedenle bağımlılıklara dikkat etmeniz gerekir. Bu kurulum package-install, tho tarafından kurulan diğer paketlerle düzgün bir şekilde etkileşime girer , bu yüzden o kadar da korkunç değildir.


2

Dahil olmak üzere bu soruya diğer cevaplar, benim diğer cevap , onun yasasında değişiklik yaparak bir Emacs paketini yamayan konuşma. Ancak bu soruyu Google aracılığıyla bulan kullanıcılar, "Emacs paketini yamala" derken başka bir şey düşünüyor olabilir - yani, kaynak kodunu değiştirmek zorunda kalmadan davranışını geçersiz kılar.

Bunu yapmak için mekanizmalar, artan saldırganlık sırasını içerir:

İlk iki seçeneğin gücüne rağmen, bazen başka bir yol olmadığından kendimi üçüncü rotayı sık sık buldum. Ama sonra soru şu ki, orijinal fonksiyon tanımı değişirse ne olur? Kopyaladığınız ve init dosyanıza yapıştırdığınız tanımın sürümünü güncellemeniz gerektiğini bilmenin hiçbir yolu yoktur!

Yamaları takıntı haline getirdiğim için el-patch, bu sorunu olabildiğince kapsamlı bir şekilde çözen paketi yazdım . Buradaki fikir, init dosyanızda, hem orijinal işlev tanımını hem de bu dosyadaki değişikliklerinizi tanımlayan s-ifadesi tabanlı farkları tanımlamanızdır. Bu, düzeltme eklerinizi çok daha okunabilir hale getirir ve düzeltme ekinizi el-patchyaptığınızdan bu yana özgün işlev tanımının güncellenip güncellenmediğini daha sonra doğrulamanıza olanak tanır . (Öyleyse, değişiklikleri Ediff üzerinden gösterecektir!) Belgelerden alıntı:

company-statisticsPakette tanımlanan aşağıdaki işlevi göz önünde bulundurun :

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

Biz üçüncü argüman değiştirmek istediğinizi varsayalım niliçin 'nomessagezaman kaydedilir mesaj bastırmak için, company-statisticsyükler istatistiklerinin dosyasını. Bunu aşağıdaki kodu yerleştirerek yapabiliriz init.el:

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

Op el-patch-defunyerine defunbir yama tanımlamak yeterlidir : yani, hiçbir etkisi yoktur (pek değil, daha sonra bakın ). Ancak düzeltme eki yönergelerini ekleyerek , işlevin değiştirilmiş sürümünü orijinalden farklı yapabilirsiniz.

Bu durumda, el-patch-swapdirektifi kullanıyoruz. el-patch-swapForm ile değiştirilir nilorijinal tanımı (olduğunu, içinde "resmi" tanımı karşılaştırılır versiyonu company-statistics.el) ve ile 'nomessagemodifiye tanımında (olduğunu, aslında İnit dosyasında değerlendirilir versiyonu).


0

Çok fazla değişiklik yaptığınızda, bence kullanmalısınız straight.el, Radon Rosborough'un cevabına bakın .

Sadece bir kereye mahsus değişiklik yapmak istiyorsanız, diyelim ki adlı bir projeyi varsayalım fork-mode, aşağıdaki adımları uygulayın:

  • Git'i depolamak için bir dizin oluşturun mkdir ~/.emacs.d/lisp-gits
  • Değiştirmek istediğiniz projenin çatalını yapın, diyelim ki https://github.com/user/fork-mode
  • Çatalını klonla cd ~/.emacs.d/lisp-gits && git clone git@github.com:user/fork-mode.git

Aşağıdaki kodu .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"))))

Artık C-h fdeğiştirmek istediğiniz işlevleri bulmak için kullanarak emacs modunu kullanabilirsiniz . Paket lisp-gits'e kurulduğunda, oraya atlayacağınızı göreceksiniz. Değişiklikleri uygulamak / göndermek için magit veya diğer git komutlarını kullanın ve sonra çekme isteklerinizi göndermek için github kullanın.

Çekme talepleriniz kabul edildiğinde, projeyi kaldırabilir ~/.emacs.d/lisp-gitsve paket yöneticisinin işini yapmasına izin verebilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.