add-hook的判断问题

我又双叒叕叕叕来伸手了…… 回来我真可能找个平台开一个“配置文件炼成记”的专栏,以纪念我无耻的伸手行为……

那么我现在碰到的问题是,我想add-hook,但是加上去的那个function可能不会被安装。 比如下面这些东西:

(unless *is-macOS*
  (maybe-require-package 'xxx))

(add-hook 'c-mode-hook 'xxx)

那么很明显,在macOS下那个xxx是不会被安装的,那么下面的add-hook需不需要加一个判断参数? 还是说,实际上我应该把add-hook直接写到unless里?

各位大神求指教!

等等……我似乎傻了……

既然我都不要那个包了,我干嘛去add-hook啊,肯定写死到一块儿啊 啊啊啊啊……

不知道对不对……这个理论

1 个赞

感觉需要视具体情况而定。

所以我才说我傻了啊…… 我的本意就是在macOS上不起用那个包,而在其他系统上启用。 但是我就是不知道,直接写死到unless里面会出事情不会……

最后的方案……

笨办法,既然一次判断不行就……两次! 先unless,然后再when……

可以利用 maybe-require-package 的返回值,假设你的 maybe-require-packagerequire 类似,成功时返回 non-nil,否则返回 nil

(unless *is-macOS*
  (and (maybe-require-package 'xxx)
       (add-hook 'c-mode-hook 'xxx)))

为什么不用use-package呢,就像这样

    (use-package xxx
      :if *system-is-mac*
      :ensure t
      :init (add-hook c-mode-hook 'xxx))

我这配置脱胎于purcell/emacs.d…… 在我还没学会一些东西以彻底不用他的框架之前,强硬塞一个use-package挺不好受的……

如果不加and会有啥后果? 这是那个 maybe-require-package 的定义:

(defun maybe-require-package (package &optional min-version no-refresh)
  "Try to install PACKAGE, and return non-nil if successful.
In the event of failure, return nil and print a warning message.
Optionally require MIN-VERSION.  If NO-REFRESH is non-nil, the
available package lists will not be re-downloaded in order to
locate PACKAGE."
  (condition-case err
      (require-package package min-version no-refresh)
    (error
     (message "Couldn't install optional package `%s': %S" package err)
     nil)))

如果 maybe-require-package 失败了的话,你还执行了 (add-hook 'c-mode-hook #'xxx) 的话,由于 xxx 不存在,打开 C 文件时会报错,受此影响 c-mode-hook 上在 xxx 之后的函数就会没有机会执行。

(unless *is-macOS*
  (when (maybe-require-package 'xxx)
       (add-hook 'c-mode-hook 'xxx)))

如果这样会咋样? 目前我没看到啥大的副作用……而且我看and的帮助没看明白……

这里 andwhen 的作用一样。

我前面没有看出来你是不明白 and / when,感觉你之前没有把你的问题说清楚。

我确实没说清楚……对不起啊。 然后,吹毛求疵的讲,用and喝用when哪个好点? 谢谢

不好说,我觉得主要看具体情况以及个人习惯(上面的例子,我觉得 when 好些,我之所以用了 and,仅仅是因为 and 可以让代码对齐)。Emacs SE 上有人问过,我对里面的解答没什么印象。