34

如果我使用C-xC-w (write-file)将当前缓冲区的内容写入新位置,那么之后我的缓冲区将访问新文件而不是原始文件。有时我想将缓冲区的副本保存到新位置,然后继续在原始位置进行编辑。

我知道我可以从 minibuffer 历史记录中删除现有文件名,然后立即(write-file)在提示符处将其拉回以重新访问原始文件,这是我目前使用的解决方法。C-xC-f (find-file)然而,这感觉很不雅。

我想知道是否(write-file)可以使用某种前缀参数来不访问缓冲区,但这似乎只会影响覆盖确认。

那么:有没有更简单的方法可以将我的缓冲区内容保存到一个文件而不改变我正在访问的文件?

4

6 回答 6

43

用 选择整个缓冲区C-xh,然后使用M-xwrite-region

于 2013-09-12T17:55:39.620 回答
6

这是基于 Inaimathi 的回答和我对此的评论,以及一些额外的调整:

  • 默认情况下提供当前文件名进行编辑,因为我个人经常想要一个变体,而且一开始就没有它有点烦人。
  • 不要在不询问用户的情况下覆盖现有文件,也不要覆盖当前缓冲区的文件。
  • 如果区域处于活动状态,则写入区域;否则写入整个(加宽的)缓冲区。
(defun my-write-copy-to-file ()
  "Write a copy of the current buffer or region to a file."
  (interactive)
  (let* ((curr (buffer-file-name))
         (new (read-file-name
               "Copy to file: " nil nil nil
               (and curr (file-name-nondirectory curr))))
         (mustbenew (if (and curr (file-equal-p new curr)) 'excl t)))
    (if (use-region-p)
        (write-region (region-beginning) (region-end) new nil nil nil mustbenew)
      (save-restriction
        (widen)
        (write-region (point-min) (point-max) new nil nil nil mustbenew)))))

(global-set-key (kbd "C-c w") 'my-write-copy-to-file)
于 2013-09-13T07:17:20.050 回答
6

如果您经常这样做以至于让您感到厌烦,您可以定义此功能

(defun write-file-copy (filename)
  (interactive "F")
  (write-region (point-min) (point-max) filename))

并将其绑定到对您有意义的东西上。

于 2013-09-12T18:14:38.590 回答
5

如果您dired-x默认需要,或者以其他方式使该dired-jump功能可用1,那么以下内容非常简单:

C-xC-jC(输入新名称)RETq

这是:

  • 跳转到dired,指向您来自的文件
  • 复制那个文件
  • 退出dired,返回文件缓冲区

1 C-hig (dired-x) Optional Installation Dired Jump RET

于 2013-09-12T21:26:48.287 回答
2

在阅读了 phils 的(dired-jump)回答后,对于不太熟悉 Dired 的人,我想到了以下方法:

M - !cp FILE NEWNAMERET

作为奖励,您可以使用制表符完成,并且您已经在FILE's 目录中,因此键入第一个文件名既好又快。

于 2013-09-13T18:03:49.400 回答
1

这是基于@phil 的响应,适用于从 Lisp 以编程方式调用。有关详细信息,请参阅文档字符串。

(defun my-backup-buffer-or-region (&optional buffer-or-name file beg end)
  "Write copy of BUFFER-OR-NAME between BEG and END to FILE.

BUFFER-OR-NAME is either a buffer object or name. Uses current
buffer when none is passed.  Uses entire buffer for region when
BEG and END are nil.  Prompts for filename when called
interactively.  Will always ask before overwriting. Returns the
name of the file written to.

See URL `https://stackoverflow.com/a/18780453/5065796'."
  (interactive)
  (let* ((buffer-or-name (or buffer-or-name (current-buffer)))
     (buffo (or (get-buffer buffer-or-name) (error "Buffer does not exist")))  ; buffer object
     (buffn (or (buffer-file-name buffo) (buffer-name buffo)))                 ; buffer name
     (beg (or beg (if (use-region-p) (region-beginning) beg)))
     (end (or end (if (use-region-p) (region-end) end)))
     (prompt (if (and beg end) "region" "buffer"))
     (new (if (called-interactively-p 'interactive)
          (read-file-name
           (concat "Write " prompt " to file: ")
           nil nil nil
           (and buffn (file-name-nondirectory buffn)))
        (or file (error "Filename cannot be nil"))))
     ;; See `write-region' for meaning of 'excl
     (mustbenew (if (and buffn (file-equal-p new buffn)) 'excl t)))
    (with-current-buffer buffo
      (if (and beg end)
      (write-region beg end new nil nil nil mustbenew)
    (save-restriction
      (widen)
      (write-region (point-min) (point-max) new nil nil nil mustbenew))))
    new))
于 2021-04-28T21:03:20.127 回答