简体   繁体   中英

how to write elisp helper function for refactoring

I am pretty new to emacs and I am not sure I understand what lisp should actually behave.

Suppose I have two function

(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))

I wrote the following function

(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)

but it does not work. I looked online and I found it is because elisp does not have closure! So, how should I refactor these two code block?

add-to-list is a function, so you need to use it with parentheses, as (add-to-list...) . Or invoke it using funcall or apply .

Elisp has closures. Do one of the following:

With file-local-variable lexical-binding non- nil :

(defun auto-complete (mode-hook backend)
  (add-hook mode-hook
    (lambda ()
       (add-to-list (make-local-variable 'company-backends) backend))))

With lexical binding you get a closure, which encapsulates an environment where variable backend is defined. Its value in that environment is the value it has when the closure is created, but the variable remains when the anonymous function is used - you can use it as a variable.

See the Elisp manual, node Using Lexical Binding .

Regardless of the value of lexical-binding :

(defun auto-complete (mode-hook backend)
  (add-hook mode-hook
     `(lambda ()
       (add-to-list (make-local-variable 'company-backends) ',backend))))

In this case, there is no closure , and there is no variable backend in the function. Instead, that variable is replaced by its value at the time and in the context where the defun is evaluated. You can use this if you do not need to use the variable when the anonymous function is called, and all you need is its value (at the time of definition of that function).

If you use a closure then the anonymous function can be byte-compiled. If you use the variable-replacement technique then it cannot - in that case, you are not creating an anonymous function at the time of defun evaluation (or for byte-compilation). Instead, you are creating a list : (lambda...) , and that list is later interpreted as a function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM