Emacs 函数返回 Symbol 的值作为变量是 void:



我对emacs是新手,但我知道足够危险。我已经从头开始构建了.emacs文件,现在将其放在org文件中。我现在正在尝试将其提升到一个新的水平,并使我的配置对自己更加用户友好。

我主要使用emacs进行写作。书籍,博客,编剧等。我正在尝试创建一个将打开多种模式并即时添加设置的功能。

例如,我在写作时使用olivetti模式。它以文本为中心。每次我都必须调整Olivetti-set宽度。我以为我会很喜欢并启用咒语检查器并关闭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

todiv global-linum-mode对于特定主要模型,请参见自动禁用特定主要模式的全局次要模式

[inasmuch as olivetti-mode是一种次要模式,在缓冲区中已经存在的任何主要模式之后启用,原始海报可能希望通过当前缓冲区中的 linum-mode 局部通过将(linum-mode -1)添加到功能my-writing的尾端(见下文)。但是,这个想法假定原始海报希望在调用my-writing之前在当前缓冲区中活跃。]

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

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

尽管flyspell-mode通常是缓冲 - 本地的,但要养成使用1参数来打开次要模式或-10的习惯将其关闭。当省略参数时,将次要模式称为ON/OFF切换。

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

没有明显的理由作为olivetti-mode-hook的一部分致电(olivetti-mode)的原因,该CC_19在初始化次要模式的尾端被自动调用,因此现在有检查以查看该模式是否具有已经启用了。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

lawlist的答案描述了如何做自己实际要完成的工作,但是您遇到的特定错误是因为Emacs Lisp(如普通LISP,但不是方案)是LISP-2。当您使用 defun 将符号与函数关联时,它不会使该符号的 value (作为变量)的功能,它使得函数该符号的值。在简化的情况下,您会遇到相同的错误:

(defun foo ()
  42)
(list foo)

符号 foo 在这里没有值作为变量。要获得以后可以将某些内容传递到 funcall >或 apply ,您需要使用符号 foo ,例如:

(funcall 'foo)
;=> 42

或表单(function foo)

(funcall (function foo))
;=> 42

可以用速记#'缩写:

(funcall #'foo)
;=> 42

您因以下原因而遇到错误

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

试图使用 my-writing 作为变量,但在该点没有可变值。

最新更新