如何让 flycheck 更懂 elisp?

这些配置明明是 Mac 平台才生效的,在 Windows 平台还要提示警告信息。

不知道有没有什么办法提高 flycheck 的检查质量?

flycheck/flymake 都不懂elisp, emacser 应该默认在这些语言默认关闭检查。

1 个赞

看来确实应该关了 flycheck。

另外,1500 行的 init.el ,检查一次在 Windows 平台竟然要花整整一分钟,在Mac 平台也要20s 以上。

flycheck 默认对于 elisp 代码所启用的检查只有 2 个:

  • emacs-lisp 通过调用 byte-compile-file 来检测错误
  • emacs-lisp-checkdoc 通过调用 checkdoc 来检测错误

你上面的例子实际上是由 byte-compile-file 导致的。

;; defconst is a special form in ‘C source code’.

;; (defconst SYMBOL INITVALUE [DOCSTRING])

;; Define SYMBOL as a constant variable.
;; This declares that neither programs nor users should ever change the
;; value.  This constancy is not actually enforced by Emacs Lisp, but
;; SYMBOL is marked as a special variable so that it is never lexically
;; bound.
(defconst *is-a-mac* nil
  "immutable?")

(setq *is-a-mac* t)

由于 defconst 只是一个标记,所以 elisp 的 byte compiler 在这里没法做 constant fold, 于是没法消除这些看似不会运行的代码。

;; 如果你是这样写的,byte compiler 自然是可以优化这个的
(when nil
  (setq mac-option-modifier nil))

如果是在 C++ 程序员的角度来看,相当于要在 elisp 里引入 constexpr 变量…

1 个赞

defconst 应该没有关系:

(when (eq system-type 'darwin)
  (setq mac-command-modifier 'meta)
  (setq mac-option-modifier 'none))

这样定义也是会有同样的警告,因为在 Window 平台,找不到 mac-command-modifiermac-option-modifier 这两个变量的声明。

system-type 也是可以修改的,它只是一个普通的变量。原因跟上面的一样,无法进行 constant fold 来消除这些表达式。

那只能绕开它,通过 custom-set-variables 来自定义变量就不会报警告了。

因为用 custom-set-variables 时实际使用的是 symbol,自然就不会直接引用这个变量了…

(setq aaa 10)
(set-default-toplevel-value 'aaa 20)

aaa

这样玩也是可以的,就是一般人都不这么玩

2 个赞

试试这样

(when (eq system-type 'darwin)
  (defvar mac-command-modifier)
  (defvar mac-option-modifier)
  (setq mac-command-modifier 'meta)
  (setq mac-option-modifier 'none))
1 个赞

:+1:这样设置是可以的。

init.el 文件末尾加入本地变量,告诉 flycheck 这个文件没有 byte-compile, 也就关闭 flycheck 了。

;; Local Variables:
;; coding: utf-8
;; no-byte-compile: t
;; End:
;;; init.el ends here
1 个赞

原来 no-byte-compile 的意义是这个