Emacs:如何在创建新窗口时创建一个新的“空”缓冲区?

21
我的Emacs在Mac OS X系统上。是否有办法使得每当我使用⌘N时,新框架默认为一个空缓冲区(就像TextEdit的工作方式一样)?我倾向于先编写内容,然后再决定适当的文件名。然而,Emacs希望我先决定文件名,然后再编写内容。我看不出任何优点。有人知道为什么Emacs会以这种方式工作吗?
基本上,如果我使用C-x 5 2,Emacs总是弹出一个带有当前正在工作的文件的框架。这很不方便。我也不希望我的Emacs弹出一个默认为*scratch*的新框架(许多谷歌搜索结果似乎建议这种方法)。我更喜欢它在新框架中暂时命名为“Untitled”的缓冲区,并且如果我再次使用⌘N,Emacs就会弹出另一个临时的“Untitled 2”缓冲区,以此类推。这样,我可以稍后决定缓冲区的文件名。

所以,只需在您找到的解决方案中将“scratch”替换为“Untitled”。 - choroba
我想要多个新的“Untitled”缓冲区。到目前为止,所有新框架都指向同一个“Untitled”缓冲区。 - Bart Simpson
缓冲区不应该有唯一的名称吗?*untitled-01* *untitled-02* *untitled-03* 如果名称不唯一,恐怕您将在每个显示该缓冲区名称的帧中查看相同的缓冲区。 - lawlist
5个回答

31

你可以使用switch-to-buffer创建新的缓冲区。按下C-x b,输入缓冲区名称,然后按下RET。如果不存在该名称的缓冲区,Emacs会自动在基本模式下创建一个新的缓冲区。你可以像往常一样使用M-x切换到其他模式,例如M-x python-mode。要更改默认缓冲区,请将major-mode的默认值设置为所需的缓冲区。

如果你想要自动选择缓冲区名称并创建一个新的窗口,你需要编写自己的命令:

(defun lunaryorn-new-buffer-frame ()
  "Create a new frame with a new empty buffer."
  (interactive)
  (let ((buffer (generate-new-buffer "untitled")))
    (set-buffer-major-mode buffer)
    (display-buffer buffer '(display-buffer-pop-up-frame . nil))))

将此绑定到C-c n
(global-set-key (kbd "C-c n") #'lunaryorn-new-buffer-frame)

现在按下C-c n会创建一个新的框架,其中包含一个名为“untitled”的新空缓冲区,其中x是连续的数字。


不错 - 我不知道有 generate-new-buffer 这个函数,所以我试图从头开始实现它。 - Tyler
@lunaryorn,我刚试了一下你的函数,它很好用!你为什么要将它绑定到(kbd "C-c n")而不是(kbd "s-n")?我更喜欢使用系统默认的CMD-n,这对我来说更直观。你是因为MELPA/ELPA包中可能存在几个潜在的键绑定冲突才这样绑定的吗? - Bart Simpson
3
根据按键绑定约定C-c <字母>的组合键是保留给用户的,因此使用C-c n是“安全”的,不会与Emacs本身或其他模式的绑定冲突。既然Emacs和任何其他规范良好的模式都不会绑定这些键,所以没有冲突的风险。当然,你可以使用任何其他绑定,只要你知道它可能会与Emacs或其他模式发生冲突即可。 - user355252
@lunaryorn,谢谢!我会记住这个快捷键设置的建议! - Bart Simpson
如果我想在同一个窗口中打开缓冲区而不是新建一个窗口怎么办?谢谢! - Dario Oddenino

7
以下内容将创建一个带有唯一名称的缓冲区。该缓冲区不与任何文件关联,因此如果/当您使用C-x C-s save-buffer命令保存时,您将被提示提供文件名。
(defun empty-frame ()
  "Open a new frame with a buffer named Untitled<N>.

The buffer is not associated with a file."
  (interactive)
  (switch-to-buffer-other-frame (generate-new-buffer "Untitled")))

当我点击发布答案按钮时,我发现@lunaryorn已经发布了类似的内容,并加入了设置主模式的另一个新要素。噢,好吧。 - Greg Hendershott

6

如果我理解你的请求正确的话,以下内容可能适合你:

(defun empty-frame ()
  (interactive)
  (let ((fl (make-temp-file "Untitled")))
    (switch-to-buffer-other-frame fl)))

这将为每个新缓冲区打开一个新的临时文件。如果您不想实际创建该文件,则可以使用以下内容代替:
(defun empty-frame ()
  (interactive)
  (let ((bn "Untitled-")
        (num 1))
    (while
        (get-buffer (concat bn (number-to-string num))) 
      (setq num (1+ num))) 
    (switch-to-buffer-other-frame
     (concat bn (number-to-string num)))))

2
不要在每次迭代中映射和搜索整个缓冲区列表。相反,使用get-buffer测试特定名称的缓冲区是否存在。但是,最好使用generate-new-buffer - user355252
好的,谢谢。我会把这个留在这里作为一个(次优的)答案。 - Tyler

4
您已经看到如何创建新的“Untitled”缓冲区的答案,但为什么Emacs要求您首先选择一个名称,一些原因是:
  • 历史原因:这就是它的工作方式,一旦习惯了,它并不比其他替代方案更糟。
  • 通常基于文件名选择主要模式和各种其他细节。 因此,您只需打开扩展名为“.tex”或“.c”的文件,而不是创建一个无标题缓冲区并必须选择将其放入LaTeX模式还是C模式。
  • 拥有文件名意味着Emacs可以使用标准的自动保存过程,而对于Untitled方法,应用程序需要有某种特殊的方法在某个“标准”位置自动保存这些Untitled文档。

3

如果不存在,C-x b *untitled* 将打开新的缓冲区。此外,请参见Emacs手册


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接