大家好,我有一个存放各种配置文件的目录 myconf
, 我在该目录下创建了一个 .dir-locals.el
文件试图将这个目录下所有配置文件打开的 major mode 设置为 conf-mode
.
参考了一下 StackOverflow How to set default major mode in directory-local file?
我在.dir-locals.el
添加了下面的代码:
((nil . ((mode . conf))))
也试着修改成
((nil . ((eval . (conf-mode)))))
可是上面两种方式都会出错,随意打开一个myconf
下面的文件,Emacs 都会给出下面的错误:
File local-variables error: (error Variable binding depth exceeds max-specpdl-size) [2 times]
请教一下大家应该如何解决这个问题呢? 我把上面代码中的 conf
或者conf-mode
改成 c
或 c-mode
是可以将 major-mode 设置成 c-mode
的。是 conf-mode
这个 major-mode 比较特殊吗?
1 个赞
cireu
2
大概emacs把目录里的某些文件解释成了conf-mode,你又设置了解析所有文件为conf-mode,然后就死循环了。
((nil . ((eval . (progn
(add-to-list 'auto-mode-alist
(cons (regexp-quote default-directory) 'conf-mode)))))))
有个比较hack的办法
Update 又试了下,发现 M-x add-dir-local-variable
有一样的问题,所以下面的结论不成立。
用 add-dir-local-variable
,而不是手写,以免出现格式问题:
M-x add-dir-local-variable nil mode conf
Emacs 会帮你写入
((nil (mode . conf)))
这跟你的 ((nil . ((mode . conf))))
在一个 Lisp 表达式的角度是 equal
的,但或许当前 Emacs 版本不支持你的写法?
File Local Variable 也是如此,应该用 M-x add-file-local-variable-prop-line
和 add-file-local-variable
,而不是手写。
感觉是个 Bug。
从 Emacs 26.1 中开始出问题的,之前的都没问题,而 Emacs 26.1 的 NEWS 没有说明有这样的不兼容行为,如果我的猜测属实,建议提交个 Bug。
貌似的确如此,譬如 conf-mode
是一个普通函数,而不是像一般的 Major Mode 使用 define-derived-mode
定义的,我试了下 conf-unix
是 OK 的。
顺便一提 ((nil (mode . conf-unix)))
作为 Directory Local Variable 杀伤力太大,把 Dired、Helm 等都给破坏了。
1 个赞
刚刚开启了 debug-on-error
,确实是存在你说的死循环的问题。这个 hack 也可以用,谢谢!
谢谢!看了不少您的回帖,学习到了很多。如果您方便的话,请帮忙提交这个 Bug 吧。
这个我也观察到了,所以给每个配置文件的开头加上了一行 # -*- mode: conf -*-
来设置 major mode, 不折腾 .dir-locals.el
了。
我的头两个回帖是错的,所以应该没这个 Bug。真正的问题应该是用 conf-unix
之类的而不是 conf
。
cireu
9
没错,用nil设置mode杀伤力太大,用eval设置auto-mode-list比较好。
我想到的是在find-file-hook
里面检查目录,再conf-mode
,但是这样可能会在conf mode之前多加载一个文件本来对应的major mode,不如cireu的办法好。
为什么?这个解释没看懂