有个kill-buffer-hook可以跟踪buffer关闭(还不确定能否涵盖所有情况), 有没有跟它对称的hook, 可以跟踪buffer创建的?
应用场景:
想让一个frame绑定和管理一个project, 每个frame有一个独立的buffer-list, 只包含对应project的文件以及文件夹buffer,还有default-directory在project里的buffer,每次打开文件或者文件夹等, 自动将对应buffer加入到对应的project的frame的buffer-list里.
本来想找一个跟kill-buffer-hook对称的hook,该hook调用的时候,buffer已创建且对应的文件或文件夹已经打开,目前看major-mode-change-hook最接近,但要处理用户故意切换了major-mode的情况。
另外,frame有个buffer-predicate属性,如果emacs内部用它来判断一个buffer是否应该在当前frame显示就简单了,目前emacs好像只用它来判断other-buffer
buffer创建没有好方法,只有一个major-mode-change-hook。一般都是自己实现这个hook
这个hook有可能是用户强制切换了某个buffer的major-mode, 如果用来更新每个frame的buffer列表, 则需要遍历每个frame保存的buffer列表, 代价较大.
如果能确定该buffer是全新创建且关联的文件(如果有的话)已经加载, 这样才好用
如果没有跟kill-buffer-hook对称的hook, 那就只能用这个了, 这个调用频率有点高
自己写一个:
(defun get-buffer-create@around (fn buffer-or-name)
(or (get-buffer buffer-or-name)
(prog1 (funcall fn buffer-or-name)
(message ">>> buffer '%s' created" buffer-or-name))))
(advice-add 'get-buffer-create :around 'get-buffer-create@around)
UPDATE:
这种方也有待完善,company、helm 弹出菜单/窗口的时侯都会创建大量的临时 buffer:
可以在 company、helm 等弹出菜单/窗口的时侯暂时禁用,以减少干扰。
即使不做任何处理,响应次数也已经比 buffer-list-update-hook 少很多了,而且可以肯定当前是在「创建」 buffer、同时也知道 buffer 名称/对象。
2 个赞
你的使用场景是什么?
不确定能不能从 buffer-list-update-hook
中区分出 Buffer 的「创建」。
如果是打开文件的话,应该是在文件打开之前调用吧?这样没法获取文件名
每当打开文件的时候,根据条件判断该文件属于哪个frame,自动加入到该frame的buffer列表。
你如果只考虑打开文件的 buffer,不考虑其它方式创建的 buffer,确实在打开文件的时侯处理更方便。
buffer 名称/对象也是可以获取到文件名的 (buffer-file-name BUFFER-OR-NAME)
UPDATE
不是有个 find-file-hook 么?
我看有些配置/包都是用自制的hook,有人在emacs-devel提过这个问题吗?
这是什么意思?Frame 的 buffer-list
参数么?但这个然后怎么用?(不熟悉 Frame)
如果要不同文件用不同的 Frame 打开,或许可以试试 display-buffer-alist
。
不单是文件, 还有dired等, 用途是, 在打开文件的时候, 自动把该buffer放到指定分组里.
如果要等到buffer对应的文件或者文件夹(dired)打开之后呢? 现在感觉这种hook很难实现, 不再考虑这种方法了.
本来是想让一个frame绑定和管理一个project, 每个frame有一个独立的buffer-list, 每次打开文件, 自动将对应buffer加入到对应的project的frame的buffer-list里.
目前看major-mode-change-hook最合适, 配合一个buffer的hash map, 重复性也可以解决. 我看有插件就是这么用的
Emacs 用到 buffer 的地方非常多,你应该一开始就把需求描述清楚,而不是盖楼一点点追加。
通常 dired 和 find-file 最后都会调用 pop-to-window
,但是在后台打开的,例如 find-file-noselect
就不会 pop 到 window。最然 revert-buffer
重新加载 buffer 内容,但它也不会调用 pop-to-window
。