我正在尝试创建一个能够从emacs'*Buffer List*
缓冲区恢复缓冲区的函数。据我所知,文档中没有办法快速执行此操作(以buff-menu.el
内置的save / mark / visit函数的方式)。所以我正在写一些elisp。这是我目前的尝试:
(defun frobnitz ()
"Call in buffer list to revert buffer at point to file."
(interactive)
(let ((buf (buffer-menu-buffer t)))
(if (y-or-n-p (concat "Revert " (buffer-name (buf)) " ?"))
(with-current-buffer buf
(let (())
(revert-buffer t t t)
(message
(concat "Reverted " (buffer-name (buf)) "to last saved state."))
)))))
不幸的是,上述修改似乎不起作用,我无法弄清楚原因。如果我评估上述内容,请切换到*Buffer List*
缓冲区,然后调用 M- :( frobnitz),然后出现以下错误。
Debugger entered--Lisp error: (void-function buffer-menu-buffer)
(buffer-menu-buffer t)
(let ((buf (buffer-menu-buffer t))) (if (y-or-n-p (concat "Revert " (buffer-name (buf)) " ?")) (with-current-buffer buf (let (nil) (revert-buffer t t t) (message (concat "Reverted " (buffer-name (buf)) "to last saved state."))))))
frobnitz()
eval((frobnitz) nil)
eval-expression((frobnitz) nil)
call-interactively(eval-expression nil nil)
似乎这告诉我没有函数buffer-menu-buffer
- 但这似乎也不太可能,因为buffer-menu-buffer
是使缓冲区菜单工作的一个非常重要的功能!出于类似的原因,我非常警惕自己弄错buffer-menu-buffer
- 我不想打破缓冲区菜单。
请记住,答案可能是“调用你忽略的这个函数”,我怎样才能完成它的目的,即直接从缓冲区菜单恢复缓冲区?
更新:正如回答者Sean所指出的那样,我正在努力工作的函数的正确名称是Buffer-menu-buffer
,首字母为B.修复了这个问题,我来了另一个:
(let (nil) (revert-buffer t t t) (message (concat "Reverted " buf-name "to last saved state.")))
(save-current-buffer (set-buffer buf) (let (nil) (revert-buffer t t t) (message (concat "Reverted " buf-name "to last saved state."))))
(with-current-buffer buf (let (nil) (revert-buffer t t t) (message (concat "Reverted " buf-name "to last saved state."))))
(if (y-or-n-p (concat "Revert " buf-name " ?")) (with-current-buffer buf (let (nil) (revert-buffer t t t) (message (concat "Reverted " buf-name "to last saved state.")))))
(let ((buf (Buffer-menu-buffer t)) (buf-name (concat "" (buffer-name (Buffer-menu-buffer t))))) (if (y-or-n-p (concat "Revert " buf-name " ?")) (with-current-buffer buf (let (nil) (revert-buffer t t t) (message (concat "Reverted " buf-name "to last saved state."))))))
frobnitz()
eval((frobnitz) nil)
eval-expression((frobnitz) nil)
call-interactively(eval-expression nil nil)
我的猜测是with-current-buffer
尝试保存当前缓冲区,这是*Buffer List*
上的禁忌。所以现在我正在寻找替代方案 - 可能只需切换,恢复并调用(buffer-list)
切换回来。
更新2:
对于未来的读者:工作函数和在buffer-menu-mode
中调用它的单键绑定:
;; Enhance the buffer menu's capabilities.
(defun revert-buffer-from-buffer-list ()
"Call in buffer list to revert buffer at point to file.
Bind this to a key in `buffer-menu-mode' to use it there - not productive in
other modes because it depends on the `Buffer-menu-buffer' function. Undefined
behavior if you invoke it on a buffer not associated with a file: that's why it
has a confirmation gate. Buffers not associated with files get to play by their
own rules when it comes to `revert-buffer' (which see)."
(interactive)
(let (
(buf (Buffer-menu-buffer t))
(buf-name (concat "" (buffer-name(Buffer-menu-buffer t))))
)
(if (y-or-n-p (concat "Revert " buf-name " ?"))
(with-current-buffer buf
(let ()
(revert-buffer t t t)
(message (concat "Reverted " buf-name " to last saved state."))
)))))
(add-hook 'Buffer-menu-mode-hook
(lambda ()
(define-key Buffer-menu-mode-map (kbd "R") revert-buffer-from-buffer-list)
))
另外要谨慎提醒:add-hook
不是幂等的,所以如果你向foo-mode-hook
添加你不打算或不工作的东西,你就有可能破坏{{1}直到你zorch foo-mode
或修剪破碎的元素。问我怎么知道!
答案 0 :(得分:4)
我的Emacs有一个功能Buffer-menu-buffer
,但没有buffer-menu-buffer
。我想这就是绊倒你。
编辑:
我发现你的代码还有两个问题,之后我可以用缓冲区菜单恢复缓冲区。
(buf)
更改为buf
。 buf
是一个变量,而不是要调用的函数。(let (()) ...)
构造导致错误。消除它,或将其更改为(let () ...)
(虽然我不知道你为什么要这样做)。