Wie öffne ich gerade getöteten Puffer, wie CSt in Firefox Browser?

35

Manchmal töte ich versehentlich einen Puffer und möchte ihn erneut öffnen, genau wie CSt, um einen geschlossenen Tab in Firefox rückgängig zu machen, aber in Emacs gibt es keinen eingebauten Befehl, der defun undo-kill-bufferin http://www.emacswiki.org/RecentFiles :

(defun undo-kill-buffer (arg)
  "Re-open the last buffer killed.  With ARG, re-open the nth buffer."
  (interactive "p")
  (let ((recently-killed-list (copy-sequence recentf-list))
     (buffer-files-list
      (delq nil (mapcar (lambda (buf)
                  (when (buffer-file-name buf)
                (expand-file-name (buffer-file-name buf)))) (buffer-list)))))
    (mapc
     (lambda (buf-file)
       (setq recently-killed-list
         (delq buf-file recently-killed-list)))
     buffer-files-list)
    (find-file
     (if arg (nth arg recently-killed-list)
       (car recently-killed-list)))))

funktioniert überhaupt nicht Wenn Sie elisp kennen, wie können Sie dieses Problem lösen?

Wenn eine Liste der geschlossenen Puffer angezeigt werden kann und ich einen von ihnen zum erneuten Öffnen auswählen kann, ist dies besser.

CodyChan
quelle
7
Keine der bisher gegebenen Antworten beantwortet die gestellte Frage, bei der es um das "Wiedereröffnen" oder Wiederherstellen eines getöteten Puffers geht. Das ist so, weil das im Allgemeinen so gut wie unmöglich ist - das Beste, was getan werden könnte, wäre, es neu zu erstellen. Aber wenn Sie nur Dateibesuchspuffer meinen, ist die Antwort einfach und die hier gegebenen Antworten sind angemessen. Wenn dies der Fall ist , bearbeiten Sie bitte Ihre Frage , um diese Einschränkung widerzuspiegeln.
Drew
2
Ein alternativer Ansatz besteht darin, diese Puffer nicht zu töten. Bury-Buffer ist schön. Sie können sich auch einen schickeren Ansatz vorstellen, z. B. einen (noch zu definierenden) Kill-Buffer-Later, der den Buffer sofort begräbt und einen Timer einrichtet, um den Buffer nach einigen Minuten zu töten. Oder ein kill-buffer-maybe-later, der den Puffer beim Aufrufen einer Datei löscht und den Tod verzögert, wenn dies nicht der Fall ist.
YoungFrog
@YoungFrog, Genau, ich habe diese Gelegenheit in meiner Antwort angesprochen.
Mark Karpov

Antworten:

27

Hier ist eine andere, einfache Alternative, die nicht benötigt wird recentf. Wenn Sie die erste Funktion einbinden, kill-buffer-hookwird der mit dem Puffer verknüpfte Dateiname in eine Liste verschoben. (Beachten Sie, dass ein Puffer, der eine Datei nicht besucht, endgültig gelöscht wird.) Die letztere Funktion entfernt diese Datei aus der Liste und ruft sie auf:

(defvar killed-file-list nil
  "List of recently killed files.")

(defun add-file-to-killed-file-list ()
  "If buffer is associated with a file name, add that file to the
`killed-file-list' when killing the buffer."
  (when buffer-file-name
    (push buffer-file-name killed-file-list)))

(add-hook 'kill-buffer-hook #'add-file-to-killed-file-list)

(defun reopen-killed-file ()
  "Reopen the most recently killed file, if one exists."
  (interactive)
  (when killed-file-list
    (find-file (pop killed-file-list))))

Beachten Sie, dass killed-file-listes sich um eine Liste handelt. Sie können also beispielsweise eine komplexere Funktion schreiben, um diese Liste zu durchlaufen, anstatt die hier beschriebene einfache: Es liegt an Ihnen, wie viel Sie damit tun möchten.

BEARBEITEN: Entschuldigung, ich habe die letzte Bestimmung in Ihrer Frage übersehen, wonach eine Liste von Dateien zur Auswahl stehen soll. Die folgende Funktion ist insofern etwas ausgefallener als die obige Version, als Sie completing-readhiermit angeben können, welche der getöteten Dateien Sie verwenden möchten. Wenn Sie so etwas verwenden ido, können Sie alle Dateien durchlaufen, die Sie in der aktuellen Sitzung getötet haben, wobei standardmäßig die neueste verwendet wird. Beachten Sie, dass vorausgesetzt wird, dass Sie bereits Folgendes benötigt haben cl-lib:

(defun reopen-killed-file-fancy ()
  "Pick a file to revisit from a list of files killed during this
Emacs session."
  (interactive)
  (if killed-file-list
      (let ((file (completing-read "Reopen killed file: " killed-file-list
                                   nil nil nil nil (car killed-file-list))))
        (when file
          (setq killed-file-list (cl-delete file killed-file-list :test #'equal))
          (find-file file)))
    (error "No recently-killed files to reopen")))
Dan
quelle
5

Ich möchte Sie fragen: "Wollen Sie es wirklich töten?". In der Tat ist das Töten eines Puffers in der Emacs-Welt so verbreitet, aber sobald er getötet wurde, ist der Puffer verschwunden, und wie Ihre Frage zeigt, ist dies nicht immer wünschenswert.

Wir können jedoch einen anderen Weg wählen, sodass Sie niemals den getöteten Puffer wiederherstellen müssen - begraben Sie lieber als töten. Schauen Sie sich das Kill or Bury Alive- Paket an, das über MELPA erhältlich ist .

Aus der Beschreibung des Pakets:

Haben Sie jemals einen Puffer zerstört, den Sie am Leben lassen möchten? Die Motivation für das Töten ist normalerweise, dass man sich vorerst aus dem Weg räumt, und das Töten ist in vielen Fällen möglicherweise nicht die beste Wahl, es sei denn, Ihr RAM ist sehr, sehr begrenzt. Dieses Paket erlaubt es Emacs zu lehren, welche Puffer wir töten wollen und welche wir am liebsten lebendig begraben.

Wenn wir wirklich einen Puffer töten wollen, stellt sich heraus, dass nicht alle Puffer auf die gleiche Weise sterben möchten. Mit dem Paket können Sie festlegen, wie verschiedene Arten von Puffern gelöscht werden sollen. Dies kann besonders nützlich sein, wenn Sie beispielsweise mit einem Puffer arbeiten, dem ein Prozess zugeordnet ist.

Aber manchmal möchten Sie vielleicht die meisten Puffer loswerden und Emacs in einen mehr oder weniger jungfräulichen Zustand versetzen. Sie möchten wahrscheinlich nicht den Arbeitspuffer und möglicherweise auch die ERC-bezogenen Puffer löschen. Sie können angeben, welche Puffer gelöscht werden sollen.

Mark Karpov
quelle
4

Ich benutze diese Lösung aus diesem SO-Beitrag und es funktioniert gut.

Die Lösung ist elegant, aber nicht perfekt. Es speichert eine Liste der aktiven Puffer und gibt die erste Datei aus der Liste der zuletzt verwendeten Puffer zurück, die nicht zur Liste der aktiven Puffer gehört.

;; Öffnen Sie den letzten getöteten Puffer erneut
;; Quelle: https://stackoverflow.com/questions/10394213/emacs-reopen-previous-killed-buffer
(erfordern 'cl)
(erfordert 'recentf)
(Recentf-Mode 1)
(Undo-Kill-Buffer defun ()
  (interaktiv)
  (let ((active-files (Schleife für Buf-In (Pufferliste)
                            Wann (Buffer-File-Name Buf) Sammle es)))
    (Schleife für Datei in RecentF-Liste
          es sei denn (Mitgliedsdatei active-files) return (find-file file)))
Kaushal Modi
quelle
3

Sie müssen einschalten recentf-mode. Um das zu tun, renne M-x recentf-mode. In diesem Fall funktioniert die Funktion möglicherweise erst, wenn Sie neue Puffer öffnen oder löschen. Ich glaube nicht, dass Sie recentf-listausgefüllt haben.

Wenn Sie möchten, dass dies beim Starten von Emacs aktiviert wird, fügen Sie dies in Ihre Init-Datei ein:

(recentf-mode)

Sie können dann das, was defunSie dort gefunden haben, hineinlegen und es an einen Schlüssel binden, wenn Sie möchten.

Ein Nachteil dieses Modus scheint darin zu liegen, dass der RecentF-Modus zum Verfolgen von openedDateien erstellt wurde, nicht zum Verfolgen von getöteten Dateien. Wenn Sie die Funktion also zweimal ausführen, wird die zuletzt getötete Datei nicht erneut geöffnet.

zck
quelle
4
Obwohl Emacs 24 dies effektiv für kleinere Modi optional gemacht hat, würde ich immer noch gerne (recentf-mode 1)mit dem expliziten Argument schreiben , damit jemand, der seine Init-Datei unter Emacs 23 erneut auswertet, den Modus nicht wieder ausschaltet.
Phils
1

ErgoEmacs hat eine Funktion, close-current-bufferdie insbesondere eine Liste kürzlich geschlossener Puffer führt:

(defvar recently-closed-buffers (cons nil nil) "A list of recently closed buffers. The max number to track is controlled by the variable recently-closed-buffers-max.")
(defvar recently-closed-buffers-max 10 "The maximum length for recently-closed-buffers.")

(defun close-current-buffer ()
"Close the current buffer.

Similar to (kill-buffer (current-buffer)) with the following addition:

• prompt user to save if the buffer has been modified even if the buffer is not associated with a file.
• make sure the buffer shown after closing is a user buffer.
• if the buffer is a file, add the path to the list recently-closed-buffers.

A emacs buffer is one who's name starts with *.
Else it is a user buffer."
 (interactive)
 (let (emacsBuff-p isEmacsBufferAfter)
   (if (string-match "^*" (buffer-name))
       (setq emacsBuff-p t)
     (setq emacsBuff-p nil))

   ;; offer to save buffers that are non-empty and modified, even for non-file visiting buffer. (because kill-buffer does not offer to save buffers that are not associated with files)
   (when (and (buffer-modified-p)
              (not emacsBuff-p)
              (not (string-equal major-mode "dired-mode"))
              (if (equal (buffer-file-name) nil) 
                  (if (string-equal "" (save-restriction (widen) (buffer-string))) nil t)
                t
                )
              )
     ;; (progn ;; I'VE ADDED THIS LINE
     ;;   (switch-to-buffer (buffer-name)) ;; AND THIS LINE
     (if (y-or-n-p
          (concat "Buffer " (buffer-name) " modified; Do you want to save?"))
         (save-buffer)
       (set-buffer-modified-p nil))
     ;; ) ;; AND ALSO A PARENTHESIS HERE
     )

   ;; save to a list of closed buffer
   (when (not (equal buffer-file-name nil))
     (setq recently-closed-buffers
           (cons (cons (buffer-name) (buffer-file-name)) recently-closed-buffers))
     (when (> (length recently-closed-buffers) recently-closed-buffers-max)
           (setq recently-closed-buffers (butlast recently-closed-buffers 1))
           )
     )

   ;; close
   (kill-buffer (current-buffer))

   ;; if emacs buffer, switch to a user buffer
   (if (string-match "^*" (buffer-name))
       (setq isEmacsBufferAfter t)
     (setq isEmacsBufferAfter nil))
   (when isEmacsBufferAfter
     (next-user-buffer)
     )
   )
 )

Wenn Sie diese also verwenden, können Sie den geschlossenen Puffer dieser Sitzung mit erneut öffnen

;; undo close this-session buffer:
(defun ergo-undo-close-buffer ()
  "Opens some this-session closed buffer."
  (interactive)
  (let* ((mylist (delq nil (delete-dups (mapcar 'car recently-closed-buffers))))
         (baseName (ido-completing-read "Open this session closed buffer: " mylist))
         (fileName (cdr (assoc baseName recently-closed-buffers))))
    (find-file fileName)))
Adobe
quelle
1

EDIT: Ich habe bei der Beantwortung nicht aufgepasst und etwas anderes beantwortet, was das OP nicht gefragt hat. Es tut mir wieder leid. Vielen Dank für Ihre Worte, @CodyChan.

Nun, ich bin kein Emacs-Veteran, und möglicherweise ist dies erst in den letzten Versionen verfügbar geworden. Ich weiß, dass ich einige Jahre später komme, aber vielleicht kann es für andere hilfreich sein, da mich meine Suche hierher gebracht hat.

Ich bin auf Emacs v25.2.1, bin recentfbereits hier verfügbar und habe eine Ready-Funktion, die genau das tut, was Sie brauchen. Ich habe es in der Vergangenheit bereits in älteren Versionen aktiviert, daher habe .emacsich:

(recentf-mode 1)
(global-set-key (kbd "C-S-t") 'recentf-open-most-recent-file)

Und das hat bei mir perfekt funktioniert. Ändern Sie natürlich die Verknüpfung für das, was Ihnen besser gefällt.

Charles Roberto Canato
quelle
2
Es sieht so aus, als ob die Funktion schon vor langer Zeit existiert hat, was 2005 laut ChangeLog-Datei im Emacs-Quellcodebaum ist. Es funktioniert, und es kann sogar funktionieren, um den geschlossenen Puffer aus der vorherigen Emacs-Sitzung erneut zu öffnen, aber es scheint, dass die geschlossenen Puffer nicht aufgelistet werden können, damit ich einen aus der Liste auswählen kann.
CodyChan
2
Es wird also nicht nur der gerade gelöschte Puffer erneut geöffnet, sondern es werden kürzlich geöffnete Dateien erneut geöffnet.
CodyChan
@CodyChan, es tut mir sehr leid und natürlich hast du recht. Das wäre die zuletzt geöffnete Datei und nicht das, wonach Sie gefragt haben. Ich werde die Antwort bald löschen. Ich entschuldige mich bei Ihnen und anderen Freunden.
Charles Roberto Canato
3
Diese Antwort muss nicht unbedingt gelöscht werden. Vielleicht möchte jemand, dass Ihre Lösung kürzlich geöffnete Dateien einfach wieder öffnet. :)
CodyChan