【问题标题】:How can I revert the buffer at point in emacs' buffer list?如何恢复 emacs 缓冲区列表中的缓冲区?
【发布时间】:2012-08-05 00:35:33
【问题描述】:

我正在尝试创建一个从 emacs 的 *Buffer List* 缓冲区恢复缓冲区的函数。据我从文档中可以看出,没有办法快速做到这一点(以buff-menu.el 内置的保存/标记/访问功能的方式)。所以我正在写一些省略号。这是我目前的尝试:

(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."))
        )))))

不幸的是,上面的 defun 似乎不起作用,我无法弄清楚原因。如果我评估上述内容,切换到*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 深表警惕——我不想破坏缓冲菜单。

请记住,答案可能是“调用您忽略的这个函数”,我怎样才能让这个 defun 实现其直接从缓冲区菜单恢复缓冲区的既定目的?


更新:正如回答者 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 添加您不打算或不起作用的内容,您可能会破坏foo-mode,直到您使用zorch @987654339 @ 或从其中删除损坏的元素。问我怎么知道的!

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    我的 Emacs 有一个函数 Buffer-menu-buffer,但没有 buffer-menu-buffer。我想这就是让你绊倒的原因。

    编辑:

    我发现您的代码还有两个问题,之后我可以使用它从缓冲区菜单中恢复缓冲区。

    • 我不得不在两个地方将(buf) 更改为bufbuf 是一个变量,而不是一个要调用的函数。
    • (let (()) ...) 构造会导致错误。要么删除它,要么将其更改为 (let () ...)(虽然我不知道你为什么要这样做)。

    【讨论】:

    • 这绝对是个问题,谢谢 - 我弄错了。现在有一个不同的问题 - 想在第 2 轮试一试吗?
    • 我独立实现了关于变量与函数的部分,但let () 的问题根本不在我的考虑范围内。感谢您清除它。功能现在可以正常工作,接受。 :)
    猜你喜欢
    • 2010-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    相关资源
    最近更新 更多