Emacs函数返回符号的值作为变量是无效的:

时间:2016-06-23 16:09:39

标签: emacs elisp

我对Emacs相当新,但我知道这很危险。我从头开始构建我的.emacs文件,现在将其放在组织文件中。我现在正试图将它提升到一个新的水平,让我的配置对我自己更友好。

我大多使用Emacs写作。书籍,博客,编剧等。我正在尝试创建一个功能,将打开多个模式并动态添加设置。

例如,我在写作时使用了olivetti-mode。它使文本居中。每次我都要调整olivetti-set-width。我以为我会想到并启用拼写检查并关闭linum模式。

但是,每次尝试时我都会收到错误:

Symbol's value as variable is void: my-writing 

任何人都可以解释我做错了什么吗?我已经谷歌了很多但是我对我正在做的事情的理解显然存在差距。

#+BEGIN_SRC emacs-lisp
(defun my-writing ()
"Start olivetti mode, set the width to 120, turn on spell-check."
((interactive)
 (olivetti-mode)
 (setq olivetti-set-width . 120)
 (flyspell-mode)
 (global-linum-mode 0)))

(add-hook 'olivetti-mode-hook 
    (lambda () olivetti-mode my-writing t))

#+END_SRC

提前谢谢你。

2 个答案:

答案 0 :(得分:2)

要针对特定​​主要模式停用global-linum-mode,请参阅automatically disable a global minor mode for a specific major mode

[因为olivetti-mode是在缓冲区中已存在的任何主要模式之后启用的次要模式,原始海报可能希望在本地关闭linum-mode < / em>在当前缓冲区中,将(linum-mode -1)添加到函数my-writing的尾端(见下文)。但是,这个想法假定原始海报希望在调用linum-mode之前在当前缓冲区中激活my-writing。]

初始问题中的函数my-writing包含一组额外的括号,应该省略,并且钩子设置不正确。

olivetti-set-width是一个带有一个参数的函数,因此您无法使用setq - 请参阅从第197行开始的函数:设置变量时使用https://github.com/rnkn/olivetti/blob/master/olivetti.el setq不是一个功能。

虽然flyspell-mode通常是缓冲区本地的,但是养成使用1的参数来打开次要模式或-1的习惯是个好主意。 0将其关闭。省略参数时,调用次模式将作为开/关切换。

除非已经附加到olivetti-mode-hook的其他项目需要优先级或使用具有缓冲区本地设置的钩子的特殊原因,否则您不需要add-hook的可选参数 - 即, APPEND和LOCAL。

没有明显的原因要求(olivetti-mode)作为olivetti-mode-hook的一部分,在初始化次要模式的尾端自动调用,所以现在有检查是否已启用该模式。此示例中包含olivetti-mode-hook以演示如何格式化其用法。但是,原始海报应考虑取消(add-hook 'olivetti-mode-hook 'my-writing),因为如果用户将调用M-x my-writing而不是M-x olivetti-mode,则似乎没有用处。钩子在后一种情况下会很有用 - 也就是说,在键入M-x olivetti-mode时 - 在这种情况下,确实没有必要将(unless olivetti-mode (olivetti-mode 1))作为my-writing的一部分。

  
#+BEGIN_SRC emacs-lisp
(defun my-writing ()
"Start olivetti mode, set the width to 120, turn on spell-check."
(interactive)
  (unless olivetti-mode (olivetti-mode 1))
  (linum-mode -1) ;; see comments above
  (olivetti-set-width 120)
  (flyspell-mode 1))

;; original poster to consider eliminating this hook
(add-hook 'olivetti-mode-hook 'my-writing)

#+END_SRC

答案 1 :(得分:2)

lawlist's answer描述了如何去做你实际想要完成的事情,但是你得到的特殊错误是因为Emacs Lisp(如Common Lisp,但不是Scheme)是一个Lisp-2。当您使用 defun 将符号与函数相关联时,它不会使该符号的(作为变量)起作用,它会使 >函数该符号的值函数。在非常简化的情况下,您会收到同样的错误:

(defun foo ()
  42)

(list foo)

符号 foo 此处没有值作为变量。要获得稍后可以传递给 funcall 应用的内容,您需要使用符号 foo ,例如:

(funcall 'foo)
;=> 42

或表格(function foo)

(funcall (function foo))
;=> 42

可以用简写#&#39;

缩写
(funcall #'foo)
;=> 42

您因以下原因而收到错误:

(add-hook 'olivetti-mode-hook 
    (lambda () olivetti-mode my-writing t))

尝试使用 my-writing 作为变量,但此时没有变量值。