2012-08-07 263 views
3

我试图创建一个函数,它将从emacs的*Buffer List*缓冲区中恢复缓冲区。据我可以从文档中看出,无法快速执行此操作(以内置于buff-menu.el的保存/标记/访问功能的方式)。所以我正在写一些elisp。这是我当前的尝试:如何恢复emacs缓冲区列表中的缓冲区?

(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来完成其直接从缓冲区菜单中恢复缓冲区的目的?


更新:作为回答者肖恩指出,我有一个艰难的时间与功能的正确名称是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 foo-mode-hook或修剪掉它的破碎元素。问我怎么知道!

回答

4

我的Emacs有一个功能Buffer-menu-buffer,但没有buffer-menu-buffer。我想那是什么让你感到沮丧。

编辑:

我发现了两个更多的问题与您的代码,在这之后我能够从它的缓冲菜单恢复缓冲区。

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

这绝对是一个问题,谢谢 - 我弄错了。现在又出现了另一个问题 - 想在第2轮尝试一下? – 2012-08-07 23:29:34

+0

我独立实现了关于变量和函数的部分,但'let()'的问题根本不在我的视线之内。谢谢你清理那个。功能现在正常工作,接受。 :) – 2012-08-07 23:52:49