1

我目前有以下内容:

(defun my-hide-code ()                                                                                                                         
  (interactive)                                                                                                                                
  (set-selective-display 2))                                                                                                                   

(defvar my-keys-minor-mode-map (make-keymap) "my-keys-minor-mode keymap.")                                                                     
(define-key my-keys-minor-mode-map (kbd "<f2>") 'my-hide-code)                                                                                 
(define-minor-mode my-keys-minor-mode                                                                                                          
  "use"                                                                                                                                        
  t " my-keys" 'my-keys-minor-mode-map)                                                                                                        
(my-keys-minor-mode 1)    

现在,我想在 (set-selective-display 2) 和 (set-selective-display 'nil) 之间切换

现在,如果我在方案中,我将创建为闭包,并且闭包将存储一个状态变量,这将让我知道我处于哪个状态,以及如何切换。

然而,Elisp 显然是一个 lisp-2,其中变量和函数具有不同的范围。鉴于此,我如何创建闭包/成为切换键?

4

3 回答 3

3

Emacs 24 支持词法绑定,因此可以编写真正的闭包。

请参阅: Emacs 24 中变量作用域的新规则是什么?

请注意,动态绑定是使 Emacs 如此可定制的很大一部分,因此,如果您正在编写可能对其他人有用的东西,请谨慎使用词法绑定——确保您使用defvar任何可能对您有用的变量覆盖的人(当然,确保您想到所有不适用于您的潜在用例!:)

对于 Emacs < 24,请参阅:

于 2012-04-16T06:10:43.057 回答
2

selective-display本身就是包含你需要检查的状态的变量,所以你可以写

(defun my-toggle-selective-display ()
  (interactive)
  (if selective-display
      (set-selective-display nil)
    (set-selective-display 2)))

至于一般的闭包,我很久以前就需要它们用于一个项目,并使用反引号替换将非内部符号插入到函数定义中以避免全局变量。例如

(fset 'toggler
      (let ((toggle-var (make-symbol "toggle")))
        (set toggle-var nil)
        `(lambda () (interactive)
           (cond (,toggle-var
                  (setq ,toggle-var nil))
                 (t
                  (setq ,toggle-var t)))
           (message "toggle is %s" ,toggle-var))))

运行时会产生

M-x toggler
toggle is t
M-x toggler
toggle is nil
M-x toggler
toggle is t
M-: (boundp 'toggle)
nil

我想这算得上是一个杂牌,但我知道没有其他方法可以在 Emacs-Lisp 中获得像闭包这样的东西。

于 2012-04-16T03:24:57.027 回答
0

这是我在其他地方给出的关于如何在 Elisp 中创建真实(非假)闭包的答案的链接:

https://stackoverflow.com/a/14088107/1857114

我使用一个我称之为defun**** 的宏。它适用于 Emacs 24.2.1,但我不确定它适用于哪些早期版本。估计 **defun特殊形式将来会升级,宏将不再需要。

于 2012-12-30T04:01:43.983 回答