[英]how to write elisp helper function for refactoring
我對emacs相當陌生,我不確定我理解Lisp的實際行為。
假設我有兩個功能
(add-hook 'python-mode-hook (lambda () add-to-list (make-local-variable 'company-backends) 'company-jedi)) (add-hook 'js2-mode-hook (lambda () add-to-list (make-local-variable 'company-backends) 'company-tern))
我寫了以下函數
(defun auto-complete (mode-hook backend) (add-hook mode-hook (lambda () add-to-list (make-local-variable 'company-backends) backend))) (auto-complete 'js2-mode-hook 'company-tern)
但它不起作用。 我在網上看了一下,發現那是因為elisp沒有關閉! 那么,我應該如何重構這兩個代碼塊?
add-to-list
是一個函數,因此您需要在括號中使用它,例如(add-to-list...)
。 或使用funcall
或apply
調用它。
Elisp 已關閉。 請執行下列操作之一 :
使用文件局部變量lexical-binding
非nil
:
(defun auto-complete (mode-hook backend)
(add-hook mode-hook
(lambda ()
(add-to-list (make-local-variable 'company-backends) backend))))
使用詞匯綁定,您將獲得一個閉包,該閉包封裝了定義了變量backend
的環境。 它在該環境中的值是創建閉包時的值,但是在使用匿名函數時該變量仍然存在-您可以將其用作變量。
請參見Elisp手冊,節點使用詞法綁定 。
無論lexical-binding
的價值如何:
(defun auto-complete (mode-hook backend)
(add-hook mode-hook
`(lambda ()
(add-to-list (make-local-variable 'company-backends) ',backend))))
在這種情況下, 沒有閉包 ,並且函數中沒有變量backend
。 而是在評估defun
的時間和上下文中將該變量替換為其值 。 如果在調用匿名函數時不需要使用變量,並且只需要其值(在定義該函數時),則可以使用此變量。
如果使用閉包,則可以對匿名函數進行字節編譯。 如果您使用變量替換技術,那么它不能-在那種情況下,您不是在defun
評估時(或用於字節編譯)創建匿名函數。 相反,您正在創建一個列表 : (lambda...)
,並且該列表稍后被解釋為一個函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.