在 Emacs 中重新打开缓冲区?

如果我不小心关闭了 Emacs 中的 抓挠缓冲区,我如何创建一个新的 抓挠缓冲区?

53006 次浏览

启用 iswitchb 模式的 C-x b *scratch* RET y RET。

除此之外就是 C-x b *scratch* RET。

然后键入 *scratch* ↩︎

创建一个也处于 lisp 交互模式的新缓冲区。

GNU Emacs 默认绑定:

C-xb *scratch* RET

或者,更详细地说

M-x switch-to-buffer *scratch* RET

*scratch*缓冲区是在启动时选择的缓冲区,具有主模式 Lisp 交互。注意: *scratch*缓冲区的模式由变量 initial-major-mode控制。

一般来说,您可以创建任意数量的“抓取”缓冲区,并按照您的选择对它们进行命名。

C-xb NAME RET

切换到缓冲区 NAME,如果它不存在则创建它。在使用 C-xC-w(或 M-xwrite-fileRET)选择应该保存的文件之前,新的缓冲区不会与磁盘上的文件关联。

M-x text-mode RET

将当前缓冲区的主要模式更改为文本模式。要查找所有可用的模式(即不需要任何新包) ,您可以通过输入以下命令获得一个列表:

M-x apropos-command -mode$ RET

几年前当我第一次开始使用 emacs 时,我发现了这一点; 我不知道现在它在哪里,但是它在我的个人空间里总是有一个家。El 档案。它确实会在谷歌搜索中弹出。

;;; Prevent killing the *scratch* buffer -- source forgotten
;;;----------------------------------------------------------------------
;;; Make the *scratch* buffer behave like "The thing your aunt gave you,
;;; which you don't know what is."
(save-excursion
(set-buffer (get-buffer-create "*scratch*"))
(make-local-variable 'kill-buffer-query-functions)
(add-hook 'kill-buffer-query-functions 'kill-scratch-buffer))


(defun kill-scratch-buffer ()
;; The next line is just in case someone calls this manually
(set-buffer (get-buffer-create "*scratch*"))


;; Kill the current (*scratch*) buffer
(remove-hook 'kill-buffer-query-functions 'kill-scratch-buffer)
(kill-buffer (current-buffer))


;; Make a brand new *scratch* buffer
(set-buffer (get-buffer-create "*scratch*"))
(lisp-interaction-mode)
(make-local-variable 'kill-buffer-query-functions)
(add-hook 'kill-buffer-query-functions 'kill-scratch-buffer)


;; Since we killed it, don't let caller do that.
nil)
;;;----------------------------------------------------------------------

我在我的.emacs 中添加以下内容:

;; bury *scratch* buffer instead of kill it
(defadvice kill-buffer (around kill-buffer-around-advice activate)
(let ((buffer-to-kill (ad-get-arg 0)))
(if (equal buffer-to-kill "*scratch*")
(bury-buffer)
ad-do-it)))

如果我不想看到 抓挠缓冲区,我按 C-x C-k,但它不会杀死它,只是放在缓冲区列表的末尾,所以我需要它,下次我不需要创建一个新的。

这是我使用的-我有这个绑定到一个方便的按键。它将您发送到 *scratch*缓冲区,而不管它是否已经存在,并将它设置为 lisp-interaction-mode

(defun eme-goto-scratch ()
"this sends you to the scratch buffer"
(interactive)
(let ((eme-scratch-buffer (get-buffer-create "*scratch*")))
(switch-to-buffer eme-scratch-buffer)
(lisp-interaction-mode)))

我过去常常使用 dwj 的解决方案,我对此感到非常高兴,直到有一天我意识到它失败了,当你实际上 重命名抓取缓冲区(例如通过保存它)。

然后我采用了这个方法,它对我很有效:

  (run-with-idle-timer 1 t
'(lambda () (get-buffer-create "*scratch*")))

正如 docstring 所说,这个函数将:

切换到抓取缓冲区。如果缓冲区不存在,创建它并将初始消息写入其中。”

这将产生一个新的缓冲区,它看起来像初始缓冲区。

(defun switch-buffer-scratch ()
"Switch to the scratch buffer. If the buffer doesn't exist,
create it and write the initial message into it."
(interactive)
(let* ((scratch-buffer-name "*scratch*")
(scratch-buffer (get-buffer scratch-buffer-name)))
(unless scratch-buffer
(setq scratch-buffer (get-buffer-create scratch-buffer-name))
(with-current-buffer scratch-buffer
(lisp-interaction-mode)
(insert initial-scratch-message)))
(switch-to-buffer scratch-buffer)))


(global-set-key "\C-cbs" 'switch-buffer-scratch)

关于 这个 EmacsWiki 页面有很多提示。

这是第一个:

一个非常简单的函数来重新创建抓取缓冲区:

(defun create-scratch-buffer nil
"create a scratch buffer"
(interactive)
(switch-to-buffer (get-buffer-create "*scratch*"))
(lisp-interaction-mode))

我将迄今为止公布的解决方案合并为一个函数:

(defun --scratch-buffer(&optional reset)
"Get the *scratch* buffer object.
Make new scratch buffer unless it exists.
If RESET is non-nil arrange it that it can't be killed."
(let ((R (get-buffer "*scratch*")))
(unless R
(message "Creating new *scratch* buffer")
(setq R (get-buffer-create "*scratch*") reset t))
(when reset
(save-excursion
(set-buffer R)
(lisp-interaction-mode)
(make-local-variable 'kill-buffer-query-functions)
(add-hook 'kill-buffer-query-functions '(lambda()(bury-buffer) nil)
)))
R))

在使用 。 emacs时应用这个函数:

(--scratch-buffer t)
(run-with-idle-timer 3 t '--scratch-buffer)

这将使抓取缓冲区在第一位坚不可摧,如果保存它将被重新创建。另外,我们可以使用一个快捷函数 scratch来快速打开缓冲区:

(defun scratch()
"Switch to *scratch*.  With prefix-arg delete its contents."
(interactive)
(switch-to-buffer (--scratch-buffer))
(if current-prefix-arg
(delete-region (point-min) (point-max))
(goto-char (point-max))))

在过去,了解 Emacs 的原始启动目录被证明是有用的。这是抓取缓冲区的 desktop-dirnamedefault-directory本地变量的值:

(defvar --scratch-directory
(save-excursion (set-buffer "*scratch*") default-directory)
"The `default-directory' local variable of the *scratch* buffer.")


(defconst --no-desktop (member "--no-desktop" command-line-args)
"True when no desktop file is loaded (--no-desktop command-line switch set).")


(defun --startup-directory ()
"Return directory from which Emacs was started: `desktop-dirname' or the `--scratch-directory'.
Note also `default-minibuffer-frame'."
(if (and (not --no-desktop) desktop-dirname)
desktop-dirname
--scratch-directory))

因此,启动目录将始终返回您的 makefile、 TODO-file 等的基本目录。在没有桌面(没有桌面命令行开关或没有桌面文件)的情况下,--scratch-directory变量将保存 Emacs 曾经启动过的目录。

我有 scratch作为一个交互式命令打开一个新的抓取缓冲区(我喜欢有几个) :

(defun scratch ()
"create a new scratch buffer to work in. (could be *scratch* - *scratchX*)"
(interactive)
(let ((n 0)
bufname)
(while (progn
(setq bufname (concat "*scratch"
(if (= n 0) "" (int-to-string n))
"*"))
(setq n (1+ n))
(get-buffer bufname)))
(switch-to-buffer (get-buffer-create bufname))
(if (= n 1) initial-major-mode))) ; 1, because n was incremented

采自: http://everything2.com/index.pl?node_id=1038451

我希望我的缓冲区是一个自动保存的实际文件,重新打开它就像打开一个文件一样简单。在启动时,我杀死默认设置,然后像这样找到自己的。

(add-hook 'emacs-startup-hook
(lambda ()
(kill-buffer "*scratch*")
(find-file "/Users/HOME/Desktop/.scratch")))

我有一个定制的 kill-buffer 函数,它基本上做同样的事情——重新打开我的个人抓取保存文件,并杀死默认抓取 如果我杀死了最后一个可见的缓冲区。

我定制了一些 desktop.el函数来加载 之后 (kill-buffer "*scratch*")(find-file "/Users/HOME/Desktop/.scratch"),这样在启动 Emacs 时,最后可见的文件就不会被默认的划痕掩盖或者被我自定义的划痕掩盖。

我喜欢使用 auto-save-buffers-enhanced,它会自动保存任何没有特别排除的文件扩展名:

Https://github.com/kentaro/auto-save-buffers-enhanced/blob/master/auto-save-buffers-enhanced.el

(require 'auto-save-buffers-enhanced)
(auto-save-buffers-enhanced t)
(setq auto-save-buffers-enhanced-save-scratch-buffer-to-file-p 1)
(setq auto-save-buffers-enhanced-exclude-regexps '("\\.txt" "\\.el" "\\.tex"))

当我想创建一个无文件访问缓冲区时,我使用了@paprika 函数的一个小小变化:

(defun lawlist-new-buffer ()
"Create a new buffer -- \*lawlist\*"
(interactive)
(let* (
(n 0)
bufname)
(catch 'done
(while t
(setq bufname (concat "*lawlist"
(if (= n 0) "" (int-to-string n))
"*"))
(setq n (1+ n))
(if (not (get-buffer bufname))
(throw 'done nil)) ))
(switch-to-buffer (get-buffer-create bufname))
(text-mode) ))

在 EmacsWiki 中找到答案: http://www.emacswiki.org/emacs/RecreateScratchBuffer

(defun create-scratch-buffer nil
"create a scratch buffer"
(interactive)
(switch-to-buffer (get-buffer-create "*scratch*"))
(lisp-interaction-mode))
(global-set-key (kbd "C-x M-z")
'(lambda ()
(interactive)
(switch-to-buffer "*scratch*")))

这样不仅可以快速切换到 *scratch*缓冲区(因为我经常这样做) ,而且可以重新创建一个 *scratch*缓冲区,如果您意外杀死它,还可以自动启用 lisp-interaction-mode。您可以随意更改装订。

注意,在 MELPA 中的 emacs 软件包 unkillable-scratch将会做到这一点。还有 scratch-persist,它将自动保存和恢复会话之间的缓冲区。

为了补充已接受的答案,如果您使用 ILO 模式(它在 C-x b之后自动完成,因此不允许您编写 *scratch*) ,那么尝试:

C-xb C-b*scratch* RET

C-x b C-b *scratch* RET