2012-08-07 255 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