【问题标题】:Re-open *scratch* buffer in Emacs?在 Emacs 中重新打开 *scratch* 缓冲区?
【发布时间】:2010-09-19 02:18:39
【问题描述】:

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

【问题讨论】:

    标签: emacs


    【解决方案1】:

    GNU Emacs 默认绑定:

    C-xb *scratch* RET

    或者,更详细的

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

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

    通常,您可以根据需要创建任意数量的“临时”缓冲区,并根据您的选择命名它们。

    C-xb NAME RET

    切换到缓冲区NAME,如果它不存在则创建它。在您使用 CxCw (或 Mx write-file RET) 选择应保存的文件。

    M-x text-mode RET

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

    M-x apropos-command -mode$ RET

    【讨论】:

    • 请注意,scratch 有一些特别之处,至少在 GNU Emacs 21 及更高版本中:切换到新的 scratch 缓冲区会将其放回原处进入 Lisp 交互模式。
    • 作为对此的快速跟进,如果您的.emacs 定义了不同的默认 scratch 模式,这将是新 scratch - 不是列表交互模式。
    【解决方案2】:

    我在我的 .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)))
    

    如果我不想看到 scratch 缓冲区,我按 Cx Ck ,但它不会杀死它,只是放在缓冲区列表的末尾,所以下次我需要它不必创建新的。

    【讨论】:

    • 当我从“ibuffer”尝试这个建议时,这个建议被忽略了。但据我所知,“ibuffer”正在使用“kill-buffer”。你能帮我吗?
    • 好吧,在图形界面scratch中点击“关闭缓冲区”就被删除了。这仅适用于 C-x k,
    【解决方案3】:

    this EmacsWiki page 上有一大堆提示。

    这是第一个:

    一个非常简单的重新创建暂存缓冲区的函数:

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

    【讨论】:

      【解决方案4】:

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

      否则只需 C-x b *scratch* RET。

      【讨论】:

      • 使用默认绑定,不需要'y RET',只需将'y'和换行符插入新创建的scratch缓冲区。
      • 糟糕,这可能来自 iswitchb-mode。对于那个很抱歉。在另一个主题上,试试 iswitchb-mode ;)
      • 不应该,而且,scratch 这个名字也没有什么特别之处。可以使用 C-x b 创建任意数量的“临时”缓冲区,名称任意。
      • *scratch* 这个名字有 的特别之处(如已接受的答案中所述)——如果您创建一个名为 *scratch* 的缓冲区,则将设置主要模式根据initial-major-mode 变量(默认为lisp-interaction-mode)。
      【解决方案5】:

      我是几年前第一次开始使用 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)
      ;;;----------------------------------------------------------------------
      

      【讨论】:

        【解决方案6】:

        正如文档字符串所说,这个函数将:

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

        这将带来一个新的暂存缓冲区,看起来像初始暂存缓冲区。

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

        【讨论】:

          【解决方案7】:

          我曾经使用 dwj 的解决方案,我对此非常满意,直到有一天我意识到它失败了,当你真正重命名暂存缓冲区(例如通过保存它)时。 p>

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

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

          【讨论】:

            【解决方案8】:

            我有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

            【讨论】:

            • 这比简单地切换到新缓冲区 (C-x b bufname RET) 有什么优势?
            • @bignose:我使用ido-mode,通常会打开很多缓冲区。使用C-x b 创建一个新缓冲区真的很乏味。我必须想出一个与任何当前存在的缓冲区都不匹配的唯一名称。
            【解决方案9】:
            (global-set-key (kbd "C-x M-z")
                            '(lambda ()
                               (interactive)
                               (switch-to-buffer "*scratch*")))
            

            这不仅会快速切换到*scratch* 缓冲区(因为我经常这样做),而且会重新创建一个*scratch* 缓冲区并在您意外杀死它时自动启用lisp-interaction-mode。随意更改绑定。

            【讨论】:

              【解决方案10】:

              请注意,MELPA 中的 emacs 包 unkillable-scratch 会执行此操作。还有scratch-persist会在会话之间自动保存和恢复缓冲区。

              【讨论】:

                【解决方案11】:

                这就是我使用的 - 我将它绑定到一个方便的按键。它会将您发送到*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)))
                

                【讨论】:

                  【解决方案12】:

                  我更喜欢让我的暂存缓冲区成为自动保存的实际文件,重新打开它就像打开文件一样简单。在启动时,我会杀死默认设置并像这样找到自己的。

                  (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 时最后可见的文件不会被默认划痕或埋没我在启动 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) ))
                  

                  【讨论】:

                    【解决方案13】:

                    我已将迄今为止发布的解决方案合并为一个功能:

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

                    所以 --startup-directory 将始终返回您的 makefile、TODO 文件等的基本目录。如果没有桌面 (--no-desktop命令行开关或没有桌面文件)--scratch-directory 变量将保存 Emacs 曾经在其下启动的目录。

                    【讨论】:

                      【解决方案14】:

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

                      【讨论】:

                        【解决方案15】:

                        要添加到已接受的答案,如果您打开了 ILO 模式(并且它在 Cx b 之后自动完成,因此不允许您编写 *scratch*),那么试试:

                        C-xb C-b*scratch* RET

                        C-x b C-b *scratch* RET

                        【讨论】:

                          【解决方案16】:

                          C-xb 然后输入*scratch* ↩︎

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

                          【讨论】:

                            猜你喜欢
                            • 2014-10-17
                            • 2010-10-22
                            • 2014-02-26
                            • 1970-01-01
                            • 2011-03-24
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多