问一个关于Spacemacs中mode-hook的问题。

首先,我是想实现这么个事:打开某个类型的文件,比如a.org,的时候,自动执行某个或某几个命令。

然后,以我有限的elispemacs知识水平,我觉得应该是这样来做:

  1. 定义一个函数来包含这些命令。比如:
    (defun apply-on-org-mode ()
      "docstring"
      (interactive)  ; is this necessary?
      (display-line-number-mode nil)
    )
    
  2. 接着,加入到相应的hook中,比如:
    (add-hook 'org-mode-hook 'apply-on-org-mode)
    

----------

这应该没问题吧?

然而在Spacemacs中却无效,我查看了org-mode-hook这个变量,自己定义的函数确实加进去了,我怀疑是hook中各个函数的执行顺序问题,尝试过把自己定义的函数放到hook的最后(append),也是无效。。。

所以,求助!

咋看上去没问题,我 copy-paste 运行了一下,报错:

File mode specification error: (void-function display-line-number-mode)

仔细看下有个 typo:number 后面差个 s

没必要。(interactive) 把一个函数变成一个命令,命令可以用 M-x 或快捷键调用,函数不行。

number应该是numbers,这个是我在这个贴子里打错了。

也许Spacemacshook做了什么修改吧,我这里不行,每次进入org-mode都要手动关闭“显示行号”。

谢谢你的回复。

在 org-mode 中可以看看 global-display-line-numbers-mode , display-line-numbers-mode 的值是否都为 nil。因为它们的值只要一个不为nil,都会显示行号

(display-line-number-mode nil)改为(display-line-number-mode -1)

附 display-line-number-mode 后接参数的描述。

If called interactively, enable Display-Line-Numbers mode if ARG is positive, and disable it if ARG is zero or negative. If called from Lisp, also enable the mode if ARG is omitted or nil, and toggle it if ARG is ‘toggle’; disable the mode otherwise.

我现在是这么做的:

(defun turn-off-them ()
  "Just turn off!"
  (display-line-numbers-mode -1)
)
(add-hook 'org-mode-hook 'turn-off-them t)

当然,这在Spacemacs中是不行的,但是呢,当我打开一个org文件之后,如果我这样做:

:(run-hooks 'org-mode-hook),它就行了,行号就不显示了!

难道说,在Spacemacs中,当我打开org文件的时候,org-mode-hook中的函数/命令等并没有被执行?

所以我又做了个实验,在上面那个函数中加入一行:(message "XXX"),来看这个函数是否执行了,结果发现,确实执行了,*message*buffer中有XXX。

额。。。

我是彻底迷茫了。。。

你难道想要的是关闭行号?nil 不是关闭的意思,恰恰相反。你需要使用非正数来关闭一个 Major Mode,一般我们使用负一。

为什么 (foo-mode nil) 是开启,而不是关闭?这不违反直觉吗?

当然这违反直觉,用 nil 和 t 分别表示关闭和打开最符合直觉。

之所以 nil 是开启,是因为这样的写法十分方便:

(add-hook 'org-mode-hook #'display-line-numbers-mode)

它等于:

(add-hook 'org-mode-hook (lambda () (display-line-numbers-mode)))

也就是 (foo-mode) 必须表示开启,现在注意 Minor Mode 的函数定义签名:

(foo-mode &optional arg)

我们知道可选参数的默认值是 nil,所以如果 (foo-mode) 表示开启, (foo-mode nil) 也必须也表示开启。

怎么关闭一个 Minor Mode?

一般用 (foo-mode -1)

怎么开启?

一般用 (foo-mode) 或(foo-mode 1)。

4 个赞

嗯,对的,我一开始确实是用错了,用了nil。

不过后来都改成-1了,可以看一下你这个回复楼上的。

不过看了你的说明才搞懂了nil在这里的作用。谢谢。