Bir kütüphaneyi yeniden yükleyebilir ve defvar yeniden atama değerlerine sahip olabilir miyim?


10

Bir kütüphane geliştiriyorum ve Emacs çıkmadan düzenledikten sonra yeniden yüklemek istiyorum (açık olduğunu varsayalım load-path):

(load-library "myname")

Bunu yaptığımda, Emacs defvar-bound değişkenlerinde değişiklik almaz .

Her üst düzey formda el ile eval-defun( C-M-x) aramak istemiyorum . Does M-x eval-buffersaygı defvar/ defcustom?


1
Belki (unload-feature 'myname)önce?
npostavs

Sadece denedim ve hayır, aksine eval-defundeğişiklikleri almıyor defvar.
JeanPierre

1
@KaushalModi: Bunun bir kopya olduğunu sanmıyorum. Bu soru defvardoğru anlıyorsam, bir dosya veya arabellekteki tüm s üzerinde hareket ile ilgilidir .
Drew

1
Normalde sadece defvarları değerlendirmek asla gerekmeyecekti. Ayrıca OP kullanarak load-filedefvarların yeniden değerlendirildiğinden emin olarak tüm dosyayı değerlendirmek istediğini ima eder.
Kaushal Modi

2
Kendi yaklaşımım, değerleri değiştirdikçe değerlendirme-defun etmektir. Benim için kullanılabilir olacak kadar seyrek. YMMV.
YoungFrog

Yanıtlar:


3

(progn (unload-feature 'your-lib) (load-library "your-lib"))

İlk emacs'dan aracılığıyla kitaplığının yüklenmesi ve kullanmayarak defvars yüklenen sürece bu çalışacaktır eval-defun, eval-buffervb

Emacs require, load-libraryvb. Kullandığınızda , hangi değişkenlerin ve işlevlerin kitaplığınızın bir parçası olduğunu izler ve kullandığınızda bunları tamamen sizin için kaldırır unload-feature.

Paketler yazarken, yukarıdaki kodu kullanmanın eval-defunyeni kod yazarken daha iyi bir çözüm olduğunu görüyorum, böylece ara durumlara girmiyorsunuz.


(info "(elisp) Loading"), (info "(elisp) Unloading")Ve unload-featureihtiyaç forcekütüphane başka kütüphane için bağımlılık ise arg. Mükemmel cevap! Emacs sürümü boşaltma sağlamaya başladığını merak ediyorum ...
gavenkoa

3

defvarbir değişkenin değerini, diyelim setqveya olduğu gibi yeniden atamaz setf. Bir değişkenin değeri olduğunda defvar , ona dokunmaz.

Gönderen defvarbireyin docstringe:

(defvar SYMBOL &optional INITVALUE DOCSTRING)

SYMBOL'u değişken olarak tanımlayın ve SYMBOL öğesini döndürün.

...

İsteğe bağlı INITVALUE bağımsız değişkeni değerlendirilir ve yalnızca SYMBOL değeri geçersizse SYMBOL ayarlamak için kullanılır . SYMBOL buffer-local ise, varsayılan değeri ayarlanan değerdir; arabellek-yerel değerleri etkilenmez. INITVALUE eksikse, SYMBOL değeri ayarlanmaz.

...

defvarSöz konusu değişkenleri, kitaplığı ilk yüklediğinizde değer vermek üzere tahmin ettiğiniz için, kitaplığı yeniden yüklemek değerleri değiştirmez.

Ayrıca bkz . Global Değişkenleri Tanımlama ile ilgili elisp manuel düğümü .

Güvenmek yerine, defvardeğerleri her zaman ile yeniden atayabilirsiniz setq. Alternatif, karmaşık bir seçenek olarak, uninternsembolleri defvaryeniden yüklediklerinde bulamazlar:

(defvar test-1 "test this")
(defvar test-2 "test this one, too")

test-1                                  ; => "test this"
test-2                                  ; => "test this one, too"

(defvar test-1 "trying to redefine")
(defvar test-2 "trying to redefine, too")

test-1                                  ; => "test this"
test-2                                  ; => "test this one, too"

(mapc #'unintern '(test-1 test-2))

test-1                                  ; => error!
test-2                                  ; => error!

(defvar test-1 "trying to redefine")
(defvar test-2 "trying to redefine, too")

test-1                                  ; => "trying to redefine"
test-2                                  ; => "trying to redefine, too"

2
Bu bağlamda, yani, bir elisp paketi geliştirirken, defvarkullanılacak doğru şeydir. setqbireysel kullanıcılar tarafından ayarlanan özelleştirmeleri hızlandıracaktır. OP, paket geliştirme sırasındadefvar değişkenlerin üzerine yazmaya zorlamak için bir yol istemektedir . Geçiş yapmak için paket serbest bırakıldığında tekrar geçiş yapılması gerekir . setqdefvar
Tyler

@Tyler, evet, defvarpaket geliştirme için uygun olduğunu kabul ediyorum . Ben sadece defvardeğerleri yeniden atama değil işaret ederken işaret ediyorum setq.
Dan

2

Bunu dene:

(defun foo ()
  "(Re-)evaluate all `defvar's in the buffer (or its restriction)."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (not (eobp))
      (when (re-search-forward "\\s-*(defvar \\([^ \t\n(\"]+\\)[ \t\n]+[^)]" nil 'MOVE)
        (let ((old-value (make-symbol "t"))
              new-value value)
          (let ((debug-on-error old-value))
            (setq value (eval-defun-2))
            (setq new-value debug-on-error))
          (unless (eq old-value new-value)
            (setq debug-on-error new-value))
          value)))))

Bu sadece eval-defunbir defvar. Tamponu (veya daraltarak kısıtlamasını), her birinde durup üzerindeki kodu defvarkullanarak dolaşır eval-defun.


1

Ben yeniden atama ile tampon yeniden değerlendirme için uygun bir çözüm olduğunu duyduktan sonra ben defvarröle üzerinde basit bir işlev yaptı eval-defun:

(defun my/eval-buffer ()
  "Evaluate entire buffer with re-assigning values to `defvar' / `defcustom'.
Useful during package development."
  (interactive)
  (save-excursion
    (beginning-of-buffer)
    (while (not (eobp))
      (eval-defun nil)
      (end-of-defun))))

eval-defun-2Uygulamadan ilham alan kod yapısı . Bu benzer bir defvar yeniden değerlendirme zorlamak nasıl? çözüm.

Başlangıçta yapı betiği ile yeniden yüklenen kitaplığı yeniden değerlendirmek için yüksek düzeyde işlev istiyorum:

(defun my/load-library (library)
  "Evaluate entire library with re-assigning values to `defvar' / `defcustom'.
Useful during package development."
  (interactive
   (list (completing-read "Load library: "
                          (apply-partially 'locate-file-completion-table
                                           load-path
                                           '("" ".el")))))
  (with-temp-buffer
    (insert-file-contents (locate-file library load-path '("" ".el")))
    (my/eval-buffer)))

Drew çözümü yuvalanmış olsa bile çalışır, defvarancak kodu tamamen anlamak zordur.

Ayrıca uninternsembol öneki / regex ( Dan'ın önerdiği gibi) dayalı tüm sembolleri düşünüyorum ama her zaman önek yazmak için tembelim ... Bkz. Tüm sembol tanımlarını belirli bir önekle nasıl bağlayabilirim?

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.