但是,出于评论中已经提到的原因,我建议不要使用Org的其他大部分内容:它很旧,并且充满了遗留和有害的做法(例如,find-file-noselect以非交互方式读取文件)。
谁能解释为什么find-file-noselect
在Elisp程序中读取文件不是一个好主意吗?有没有更好的办法?我问是因为我正在考虑在我的一个项目中使用它。
good-practices
应该属于SE 所不赞成的“元标记”类别。
但是,出于评论中已经提到的原因,我建议不要使用Org的其他大部分内容:它很旧,并且充满了遗留和有害的做法(例如,find-file-noselect以非交互方式读取文件)。
谁能解释为什么find-file-noselect
在Elisp程序中读取文件不是一个好主意吗?有没有更好的办法?我问是因为我正在考虑在我的一个项目中使用它。
good-practices
应该属于SE 所不赞成的“元标记”类别。
Answers:
TL; DR:由于find-file-noselect
您无法控制实际发生的情况,最终可能会在缓冲区中启用任意次要模式,具体取决于用户在中启用了什么init.el
。此外,清理工作很困难。
使用with-temp-buffer
和insert-file-contents
代替。如果您在缓冲区中需要特定的主要或次要模式,请显式启用它们。要写入文件,请改用with-temp-file
(尽管其名称),但您可以写入任意文件。
find-file-noselect
有很多副作用,包括
find-file-hook
。普通模式本身
由于所有钩子均已运行,因此您会获得用户在其中启用的所有次要模式和钩子功能init.el
,这可能会导致各种情况,从次要不便(如果启用了不希望的次要模式)到重大破坏(如果用户添加了一个预期会导致不便的钩子功能)从交互式上下文中调用)。
有关示例,请参见https://github.com/flycheck/flycheck/issues/366。使用find-file-noselect
导致数据文件由Flycheck进行语法检查,并且由于它是在Emacs关闭时发生的,因此没有时间再次进行适当清理,从而留下了临时文件。
有了find-file-noselect
你需要格外小心再次杀缓冲区。 find-file-noselect
不会为您做到这一点。
您需要记住某个地方的缓冲区,并谨慎使用unwind-protect
以确保即使在非本地退出的情况下缓冲区也被杀死。
要读取文件,请使用with-temp-buffer
和insert-file-contents
,它只做最基本的事情,例如编码系统转换,但不问问题,启用钩子或设置局部变量:
(with-temp-buffer
(insert-file-contents (locate-user-emacs-file "foo.el"))
;; Enter the major mode explicitly
(emacs-lisp-mode)
;; …
)
with-temp-buffer
请注意适当地杀死其主体末端的临时缓冲区。
要写入文件,请使用with-temp-file
,它会创建一个临时缓冲区,并将内容写入文件体末尾的给定文件名:
(with-temp-file (locate-user-emacs-file "foo.el")
(prin1 (list 'my 'data) (current-buffer)))
根据Elisp手册的24.3节:
要将文件的内容复制到缓冲区中,请使用函数
insert-file-contents
。(不要insert-file
在Lisp程序中使用该命令,因为那样会设置标记。)
在Elisp文档中搜索find-file-noselect
很明显,它所做的不仅仅是将文件读入缓冲区。也许认为使用此功能不是一个好主意的人正在考虑可能有害的副作用?我想这取决于您要实现的目标。如果您想拥有尽可能干净/原始的缓冲区内容,则最好使用旧的和可信赖的with-temp-buffer
+ insert-file-contents
组合。如果你想在缓冲区的内容要尽可能接近到什么find-file
产生,也许你也想用find-file-noselect
?也许他正在考虑find-file
;)
find-file
过程。
good-practices
标签。使用它是一个好主意吗?