Saya menulis sebuah fungsi, dan saya ingin menyebutnya melalui Mx, dan mengikatnya ke sebuah tombol. Ini adalah fungsi saya:
(defun my-function ()
(message "This is a great function"))
Jika saya mencoba memanggilnya M-x my-function
, saya mendapatkan kesalahan: [no match]
di mini-buffer.
Jika saya mencoba mengikatnya ke tombol (atau klik mouse):
(global-set-key (kbd "C-c a") 'my-function)
Tampaknya berfungsi, tetapi ketika saya mencoba memanggilnya C-c a
, saya mendapatkan kesalahan
Argumen tipe yang salah: commandp, my-function
Mengapa saya tidak bisa menggunakan fungsi saya?
functions
commands
interactive
Tyler
sumber
sumber
interactive
- misalnya, kadang-kadang sebuah perintah menghilang dari versi baru perpustakaan. Kesalahan dapat dimunculkan dalam konteks apa pun di mana Emacs mengharapkan perintah.commandp
, untuk mencoba menemukan Qs lain yang dapat ditutup sebagai duplikat dari wiki ini. Berhati-hatilah untuk membaca T&J, karena ada beberapa yang berbeda. Dalam beberapa kasus, jawabannya (dan konteks Q) mungkin perlu diulang di sini. Dalam kasus lain , pertanyaannya tidak terkait dan harus dibiarkan apa adanya (tidak tertutup).Jawaban:
Titik intinya adalah bahwa ada perbedaan antara fungsi dan perintah .
Dalam Emacs lisp, fungsi tidak dapat dipanggil secara interaktif secara default. Itu berarti Anda tidak dapat mengaksesnya melalui
M-x
atau mengikat mereka ke tombol atau klik mouse. Jika Anda ingin melakukan itu, Anda harus secara eksplisit mendeklarasikan fungsi tersebutinteractive
, yang Anda lakukan dengan menambahkan(interactive)
formulir sebagai baris pertama dalam tubuh (mengikuti string dokumentasi). Fungsi interaktif disebut perintah. Ini dijelaskan dalam manual:(info "(elisp) Using Interactive")
(versi online) .Pesan kesalahan yang Anda lihat,,
Wrong type argument: commandp, my-function
menunjukkan bahwa Anda mencoba memanggil suatu fungsi secara interaktif, tetapi fungsi itu bukan perintah .Untuk menjelaskan kesalahan yang sebenarnya, surat
p
itu sering digunakan dalam lisp untuk menunjukkan predikat atau tes. Dalam kasus ini, Emacs sedang mengujimy-function
untuk melihat apakah itu adalah perintah menggunakan tescommandp
. Bukan, yang mengarah ke kesalahan. Kesalahan serupa muncul setiap kali Anda menggunakan objek dengan tipe yang salah: jika Emacs mengharapkan string dan Anda melewati simbol, Anda mungkin melihat referensistringp
, misalnya.Untuk menjawab pertanyaan saat ditanyakan, Anda perlu menambahkan
(interactive)
baris ke definisi:Ada banyak opsi untuk
interactive
formulir, mendukung semua jenis cara menyampaikan informasi ke fungsi Anda. Periksa manual untuk semua detail.Makro keyboard adalah kasus khusus dalam konteks ini. Makro keyboard adalah urutan acara input, direpresentasikan sebagai string. Makro keyboard berperilaku seperti perintah, sehingga Anda dapat mengikatnya ke tombol tanpa khawatir menambahkan
interactive
deklarasi. Misalnya, berikut ini:"λ"
adalah makro keyboard, jadi kita dapat mengikatnyaC-c l
tanpa masalah. Jika kita mencoba melakukan hal yang sama dengan suatu fungsi, kita harus memastikan untuk mendefinisikan fungsi sebagaiinteractive
:sumber
M-x my-function
dalam contoh Anda. Juga sebagai seorang pemula emacs, saya benar-benar belum 100% jelas tentang apa tepatnyaC-x C-e
atau kapan Anda perlu menjalankannya, tetapi tampaknya uh ... ketika Anda menjalankannya, ia mem-parsing buffer dan menimpamy-function
dalam memori karena jika saya jangan lariC-x C-e
M-x
menjalankan fungsi dari terakhir kali saya berlariC-x C-e
C-x C-e
mengevaluasi buffer , tampaknya hasil mengevaluasi buffer yang mengandungdefun
mendaftarkan fungsi, meskipun artikel ini tampaknya membuat saya berpikir bahwa itu hanya menjalankan fungsi, namun satu-satunya hal yang ditunjukkan dalam minibuffer adalahmy-function
(menyiratkan itu mengembalikan fungsi?), bukanThis is a great function
. Saya pasti kehilangan sesuatu di sini.