Điểm cốt lõi là có sự khác biệt giữa hàm và lệnh .
Trong lac Emacs, các chức năng không thể gọi tương tác theo mặc định. Điều đó có nghĩa là bạn không thể truy cập chúng thông qua M-x
hoặc liên kết chúng với một phím hoặc nhấp chuột. Nếu bạn muốn làm điều đó, bạn cần khai báo rõ ràng hàm sẽ được interactive
thực hiện bằng cách thêm một (interactive)
biểu mẫu làm dòng đầu tiên trong phần thân (theo chuỗi tài liệu). Một chức năng tương tác được gọi là lệnh Điều này được giải thích trong hướng dẫn: (info "(elisp) Using Interactive")
(phiên bản trực tuyến) .
Thông báo lỗi bạn thấy, Wrong type argument: commandp, my-function
cho biết bạn đang cố gắng gọi một chức năng một cách tương tác, nhưng chức năng đó không phải là một lệnh .
Để giải thích lỗi thực tế, chữ cái p
thường được sử dụng trong lisp để chỉ vị ngữ hoặc kiểm tra. Trong trường hợp này, Emacs đang thử nghiệm my-function
để xem đó có phải là lệnh sử dụng thử nghiệm hay không commandp
. Nó không, dẫn đến lỗi. Các lỗi tương tự bật lên bất cứ khi nào bạn sử dụng một đối tượng sai loại: nếu Emacs mong đợi một chuỗi và bạn truyền một ký hiệu, chẳng hạn, bạn có thể thấy một tham chiếu đến stringp
.
Để trả lời câu hỏi như đã hỏi, bạn cần thêm (interactive)
dòng vào định nghĩa:
(defun my-function ()
(interactive)
(message "This is a great function"))
Có rất nhiều tùy chọn cho interactive
biểu mẫu, hỗ trợ tất cả các cách truyền thông tin đến chức năng của bạn. Kiểm tra hướng dẫn cho tất cả các chi tiết.
Macro bàn phím là một trường hợp đặc biệt trong bối cảnh này. Một macro bàn phím là một chuỗi các sự kiện đầu vào, được biểu diễn dưới dạng một chuỗi. Các macro bàn phím hoạt động giống như các lệnh, vì vậy bạn có thể liên kết chúng với các phím mà không cần lo lắng về việc thêm một interactive
khai báo. Ví dụ: trong các mục sau:
(global-set-key (kbd "C-c l") "λ")
"λ"
là một macro bàn phím, vì vậy chúng ta có thể liên kết nó C-c l
mà không gặp vấn đề gì. Nếu chúng ta cố gắng làm điều tương tự với một hàm, chúng ta phải chắc chắn xác định hàm là 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 λ