Firefox 브라우저에서 CSt와 같이 방금 죽은 버퍼를 다시 여는 방법은 무엇입니까?


35

때로는 실수로 버퍼를 죽이고 CSt처럼 Firefox에서 닫힌 탭을 실행 취소하는 것처럼 다시 열려고하지만 Emacs defun undo-kill-buffer에는 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)))))

전혀 작동하지 않습니다. elisp를 알고 있다면이 문제를 해결하는 방법은 무엇입니까?

닫힌 버퍼 목록을 표시 할 수 있고 다시 열 버퍼를 선택할 수 있다면 더 좋습니다.


7
지금까지 주어진 답변들 중 어느 것도 제기 된 버퍼에 대한 "다시 열기"또는 복원에 관한 질문에 대해 응답하지 않았습니다. 그것은 일반적으로 거의 불가능하기 때문입니다. 가능한 최선의 방법은 그것을 재창조하는 것입니다. 그러나 파일 방문 버퍼 만 의미한다면 대답이 쉽고 여기에 주어진 대답이 적합합니다. 이 경우이 제한 사항 을 반영하도록 질문편집하십시오 .
Drew

2
다른 방법은 해당 버퍼를 종료하지 않는 것입니다. 매설 버퍼가 좋습니다. 또한 버퍼를 즉시 묻고 몇 분 후에 버퍼를 죽 이도록 타이머를 설정하는 (아직 정의되지 않은) kill-buffer-later와 같은 더 멋진 접근 방식을 상상할 수 있습니다. 또는 kill-buffer-maybe-later는 파일을 방문하는 경우 버퍼를 죽이고 파일이 없으면 죽임을 지연시킵니다 (Cx b를 사용할 때 혼란을 피하기 위해 이름에 공백을 추가 할 수도 있습니다).
YoungFrog

@YoungFrog, 정확히, 나는이 기회를 내 대답으로 해결했습니다.
마크 카르 포프

답변:


27

여기에 필요없는 또 다른 간단한 대안이 recentf있습니다. 첫 번째 함수에 연결하면 kill-buffer-hook버퍼와 관련된 파일 이름이 목록으로 푸시됩니다. (파일을 방문하지 않는 버퍼를 죽이면 잘 사라집니다.) 후자의 함수는 해당 파일을 목록에서 꺼내서 방문합니다.

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

killed-file-list당신이 그것으로하고 싶은 얼마나까지 : 당신은, 예를 들어, 간단한 여기에 설명하기보다는, 그 목록을주기에 더 복잡한 함수를 작성할 수 있도록 목록입니다.

편집 : 죄송합니다. 선택할 파일 목록을 원한다는 Q의 마지막 조항을 놓쳤습니다. 다음 함수는 completing-read원하는 킬된 파일을 지정할 수있는 한 위의 버전보다 약간 더 우수합니다 . 과 같은 것을 사용하는 경우 ido현재 세션에서 죽인 모든 파일을 순환하며 기본값은 최신입니다. 이미 필요한 것으로 가정합니다 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")))

5

“정말로 죽이고 싶습니까?”라고 묻고 싶습니다. 실제로, Emacs 세계에서 버퍼를 죽이는 것은 흔한 일이지만 일단 종료되면 버퍼가 사라지고 질문에서 알 수 있듯이 항상 바람직하지는 않습니다.

그러나 다른 방법을 선택할 수 있으므로 킬 버퍼를 복원 할 필요가 없습니다. 죽이기보다는 묻기를 선호합니다. 한 번 봐 가지고 킬 또는 살아 묻어 패키지, 그건 MELPA를 통해 가능합니다 .

패키지 설명에서 :

살아 남길 원하는 버퍼를 죽인 적이 있습니까? 살인 동기는 일반적으로“지금은 나가십시오”. RAM이 매우 제한적이지 않은 한 많은 경우에 살인이 최선의 선택이 아닐 수도 있습니다. 이 패키지는 Emacs에게 우리가 죽이고 싶은 버퍼와 어떤 것을 묻고 싶어하는지 알려줄 수 있습니다.

버퍼를 실제로 죽이고 싶을 때 모든 버퍼가 같은 방식으로 죽기를 원하지는 않습니다. 패키지는 다양한 종류의 버퍼 를 종료하는 방법 을 지정할 수 있습니다 . 예를 들어 관련 프로세스가있는 일부 버퍼로 작업 할 때 특히 유용합니다.

그러나 때로는 대부분의 버퍼를 제거하고 이맥스를 다소 버진 상태로 만들고 싶을 수도 있습니다. 스크래치 버퍼 및 ERC 관련 버퍼도 제거하고 싶지 않을 것입니다. 제거 할 버퍼를 지정할 수 있습니다.


4

이 SO 게시물 에서이 솔루션을 사용하면 정상적으로 작동합니다.

해결책은 우아하지만 완벽하지는 않습니다. 활성 버퍼 목록을 저장하고 활성 버퍼 목록에 속하지 않은 recentf-list에서 첫 번째 파일을 리턴합니다.

;; 마지막으로 종료 된 버퍼를 다시 엽니 다
;; 출처 : https://stackoverflow.com/questions/10394213/emacs-reopen-previous-killed-buffer
( 'cl 필요)
( '최근에 필요하다')
(최근 모드 1)
(데펀 언 킬킬 버퍼 ()
  (대화식)
  (let ((active-files (버퍼 목록의 buf에 대한 루프)
                            언제 (버퍼 파일 이름 buf) 수집))))
    (최근 f- 목록에있는 파일의 루프
          (멤버 파일 활성 파일)이 (찾기 파일 파일)을 반환하지 않는 한)))

3

을 켜야합니다 recentf-mode. 그렇게하려면을 실행하십시오 M-x recentf-mode. 그런 다음 새 버퍼를 열거 나 종료 할 때까지 함수가 작동하지 않을 수 있습니다. 나는 당신이 recentf-list채워 줄 것이라고 생각하지 않습니다 .

Emacs가 시작될 때이 기능을 사용하려면 init 파일에 넣으십시오 :

(recentf-mode)

그런 다음 defun찾은 것을 거기에 넣고 원하는 경우 키에 바인딩 할 수 있습니다.

이 모드의 한 가지 단점은 최근 f 모드가 opened파일 을 추적하기 위해 만들어졌지만 파일을 죽이지 않는 것입니다. 따라서 함수를 두 번 실행하면 가장 최근에 종료 된 파일이 다시 열리지 않습니다.


4
Emacs 24는 마이너 모드에서이 옵션을 효과적으로 선택했지만, 여전히 (recentf-mode 1)명백한 인수 로 작성 하는 경향이있어서 Emacs 23에서 init 파일을 다시 평가하는 사람은 모드를 다시 끄지 않아도됩니다.
phils

1

ErgoEmacs에는 close-current-buffer특히 최근에 닫힌 버퍼 목록을 유지 하는 기능 이 있습니다.

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

따라서이 것을 사용하면이 세션 닫힌 버퍼를 다시 열 수 있습니다.

;; 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)))

1

편집 : 나는 대답 할 때주의를 기울이지 않았고 OP가 요청하지 않은 다른 것에 대답했습니다. 다시 한 번 죄송합니다. @CodyChan, 감사합니다.

글쎄, 나는 Emacs 베테랑이 아니며 아마도 아마도 최신 버전에서만 사용 가능했을 것입니다. 나는 몇 년 후에 올 것이라는 것을 알고 있지만 내 검색으로 나를 데려온 이후 다른 사람들에게 도움이 될 수 있습니다.

저는 Emacs v25.2.1을 recentf사용하고 있으며 여기에서 이미 사용할 수 있으며 필요한 기능을 수행 할 수있는 준비된 기능이 있습니다. 이전 버전에서 이미 활성화 했으므로 .emacs다음을 수행하십시오.

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

그리고 이것은 나를 위해 완벽하게 작동했습니다. 물론 더 좋아하는 것에 대한 바로 가기를 변경하십시오.


2
Emacs 소스 코드 트리의 ChangeLog 파일에 따르면이 기능은 이미 오래 전에 존재했던 것 같습니다. 작동하지만 이전 Emacs 세션에서 닫힌 버퍼를 다시 열 수도 있습니다.하지만 닫힌 버퍼를 나열하여 목록에서 하나를 선택할 수는 없습니다.
CodyChan

2
따라서 킬된 버퍼 만 다시 열지 않고 최근에 연 파일을 다시 엽니 다.
CodyChan

@CodyChan, 정말 죄송합니다. 물론 그렇습니다. 그것은 당신이 요청한 것이 아니라 가장 최근에 열린 파일 일 것입니다. 답변을 곧 삭제하겠습니다. 귀하 및 다른 동료에게 사과드립니다.
찰스 로베르토 카나 토

3
이 답변을 불필요하게 삭제하면 누군가가 솔루션에서 최근에 연 파일을 다시 열기를 원할 수도 있습니다. :)
CodyChan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.