Neden işlevimi bir tuşa bağlayamıyorum veya Mx ile çağıramıyorum?


13

Bir işlev yazdım ve Mx ile çağırmak ve bir anahtara bağlamak istiyorum. Bu benim fonksiyonum:

(defun my-function ()
    (message "This is a great function"))

Aramaya çalışırsam , mini-buffer'da M-x my-functionhatayı alıyorum [no match].

Bir tuşa (veya fare tıklatmasına) bağlamaya çalışırsam:

(global-set-key (kbd "C-c a") 'my-function)

Çalışıyor gibi görünüyor, ancak onu aramaya çalıştığımda C-c ahatayı alıyorum

Yanlış tür argümanı: commandp, my-function

İşlevimi neden kullanamıyorum?


5
Bu soruyu, bu konuda sık sorulan sorulara genel bir cevap olarak gönüllü olarak sunuyorum. Genişletmek veya açıklığa kavuşturmaktan çekinmeyin, ancak soruyu ve cevabı benzer problemleri olan kişiler tarafından keşfedilebilir ve yararlı hale getirmek mantıklıdır!
Tyler

1
Bunu yaptığınız için teşekkürler Tyler. Q'yu lütfen bunu bir topluluk sorusuna dönüştürmesi için bir moderatör olarak işaretledim.
Drew

Merak ettiğim bir şey, başlığın sadece hata mesajını vermesi gerekip gerekmediğidir. Bu, insanların bulması daha kolay olabilir ve sadece eklemeyle ilgili olmayan cevaplara izin verebilir interactive- örneğin, bir komut bir kütüphanenin yeni bir sürümünden kaybolur. Hata, Emacs'ın bir komut beklediği herhangi bir bağlamda ortaya çıkabilir.
Drew

İnsanların şimdi wiki'yi araştırması, örneğin, commandpbunun kopyası olarak kapatılabilecek diğer Q'ları bulmaya çalışmak iyi olurdu . Bununla birlikte, bazıları farklı olduğu için Soru ve Cevapları okumaya dikkat edin. Bazı durumlarda, cevap (ve Q bağlamı) burada tekrar etmeye değer olabilir. Gelen diğer durumlarda soru ilgisiz dir (kapatılmamış) olarak bırakılmalıdır.
Drew

1
@Bunu başlığında 'reklamını' en iyi nasıl yapacağımdan emin değildim. Komut hatası yalnızca tuş bağlamalarıyla açılır, bu nedenle Mx yönünden buna giren insanlar bağlantıyı görmez. Net, özlü bir başlık ile alakalı tüm arama sorguları için açılacak bir başlık arasında en iyi dengenin ne olduğundan emin değilim. İstediğiniz gibi ince ayar yapmaktan çekinmeyin!
Tyler

Yanıtlar:


22

Temel nokta, bir fonksiyon ve bir komut arasında bir fark olmasıdır .

Emacs lisp'de işlevler varsayılan olarak etkileşimli olarak çağrılamaz. Bu, M-xonlara bir tuş veya fare tıklamasıyla erişemeyeceğiniz veya bağlanamayacağınız anlamına gelir . Bunu yapmak istiyorsanız , gövdede ilk satır olarak interactivebir (interactive)form ekleyerek (belge dizesini izleyerek) işlevi açıkça belirtmeniz gerekir . Etkileşimli bir işleve komut denir Bu kılavuzda açıklanmıştır: (info "(elisp) Using Interactive") (çevrimiçi sürüm) .

Gördüğünüz hata mesajı, Wrong type argument: commandp, my-functionbir işlevi etkileşimli olarak çağırmaya çalıştığınızı gösterir, ancak bu işlev bir komut değildir .

Gerçek hatayı açıklamak için, mektup plisp'de genellikle bir yüklemi veya testi belirtmek için kullanılır. Bu durumda Emacs, testi my-functionkullanan bir komut olup olmadığını test ediyor commandp. Hataya yol açmaz. Yanlış türdeki bir nesneyi her kullandığınızda benzer hatalar ortaya çıkar: Emacs bir dize beklerse ve bir sembol iletirseniz, stringpörneğin bir başvuru görebilirsiniz .

Soruyu sorulduğu gibi cevaplamak (interactive)için, tanıma satır eklemeniz gerekir :

(defun my-function ()
    (interactive)
    (message "This is a great function"))

Form için, işlevinize bilgi aktarmanın her türlü yolunu destekleyen birçok seçenek vardır interactive. Tüm ayrıntılar için kılavuza bakın.

Klavye makroları bu bağlamda özel bir durumdur. Klavye makrosu, dize olarak gösterilen bir dizi girdi olayıdır. Klavye makroları komutlar gibi davranır, böylece bir interactivebildirim eklemeden endişe etmeden onları tuşlara bağlayabilirsiniz . Örneğin, aşağıdakilerde:

(global-set-key (kbd "C-c l") "λ")

"λ"bir klavye makrosudur, bu yüzden C-c lsorunsuz bir şekilde bağlayabiliriz . Bir işlevi aynı şeyi yapmaya çalışırsak, işlevi şu şekilde tanımladığımızdan emin olmalıyız interactive:

(global-set-key (kbd "C-c k") 
  (lambda () (insert "λ"))
;; C-c k is undefined! We tried to bind it to a function

(global-set-key (kbd "C-c m") 
  (lambda () (interactive) (insert "λ"))
;; C-c m is bound to a command that inserts λ

Eklemek istediğim bir öneri , örneğinizde yapmadan önce Cx Ce yapmanız gerektiğini açıkça belirtin M-x my-function. Ayrıca bir emacs acemi olarak C-x C-e, tam olarak ne yaptığına veya ne zaman çalıştırmanız gerektiğine dair henüz% 100 net değilim , ancak uh ... çalıştırdığınızda, arabelleği ayrıştırır ve my-functionbellekte üzerine yazar çünkü koşma C-x C-e M-xfonksiyonu ben koştum son kez çalışırC-x C-e
jrh

Bu C-x C-e tamponu değerlendirir gibi görünüyor, a içeren bir tamponu değerlendirmenin sonucu defunişlevi kaydettiriyor gibi görünüyor , ancak bu makale bana sadece işlevi çalıştırması gerektiğini düşündürüyor ve yine de minibuffer'da gösterilen tek şey my-function(bu işlevi döndüren ima?) değil, This is a great function. Burada bir şeyi kaçırıyor olmalıyım.
jrh

1
Yorumlarınız için teşekkürler, @ jr. Bu soru ve cevap, elisp'in belirli bir yönünü, bir işlevi nasıl etkileşimli hale getirmeyi (yani işlevi bir komuta dönüştürmeyi) ele almaktadır. Elisp'in daha temel yönlerini soruyorsunuz ve bu sorunun kapsamı dışındasınız. Emacs Lisp Intro ile çalışmanızı tavsiye ederim. Bir işlev tanımını değerlendirme (bir-) bir işlevi tanımlayan ancak aslında çağırmayan ve işlev kodunu çalıştıran işlevi çağıran arasındaki fark konusunda kafanız karışmış gibi görünüyor.
Tyler
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.