如何在Emacs的缓冲区列表中恢复光标处的缓冲区?

3

我正在尝试创建一个函数,以便从emacs的*Buffer List*缓冲区中还原缓冲区。据我所知,根据文档,没有一种快速的方法可以做到这一点(就像内置于buff-menu.el的保存/标记/访问函数那样)。因此,我正在编写一些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."))
        )))))

很不幸,上面的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指出的那样,我遇到困难的函数的正确名称是以大写B开头的Buffer-menu-buffer。解决了这个问题后,我又遇到了另一个问题:
  (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 直到您清空 foo-mode-hook 或将其中的错误元素修剪掉。问我怎么知道的!
1个回答

4

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

编辑:

我发现了你代码中的另外两个问题,在解决后我可以使用它从缓冲区菜单中还原缓冲区。

  • 我必须在两个地方将(buf)更改为bufbuf是一个变量,不是要调用的函数。
  • (let (()) ...)结构会导致错误。要么消除它,要么将其改为(let () ...)(尽管我不知道你为什么要这样做)。

那绝对是个问题,谢谢 - 我弄错了。现在又出现了一个不同的问题 - 你想试试第二轮吗? - Brighid McDonnell
我独立意识到了变量与函数的区别,但是let ()的问题完全没有在我的视线范围内。感谢您澄清这一点。现在函数已经正确运行,接受。 :) - Brighid McDonnell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接