Emacsで開いているファイルの名前を変更するにはどうすればよいですか?


237

Emacsで開いているファイルの名前を変更する方法はありますか?見ながら?名前を付けて保存のようなものですが、元の名前は消えるはずです。

回答:


88

Steve Yeggeの.emacsからこの関数を試してください

;; ソース:http://steve.yegge.googlepages.com/my-dot-emacs-file
(defun rename-file-and-buffer(new-name)
  「現在のバッファとそれがNEW-NAMEにアクセスしているファイルの両方の名前を変更します。」
  (インタラクティブ「s新しい名前:」)
  (let((name(buffer-name))
        (ファイル名(バッファファイル名)))
    ((ファイル名ではない場合)
        (メッセージ「バッファ '%s'はファイルを訪問していません!」の名前)
      (if(get-buffer new-name)
          (メッセージ「「%s」という名前のバッファはすでに存在します!」新しい名前)
        (予測
          (名前変更ファイルファイル名新しい名前1)
          (名前変更バッファの新しい名前)
          (set-visited-file-name new-name)
          (set-buffer-modified-p nil)))))))

そのページを見てください。「move-buffer-file」と呼ばれる、本当に便利な関連関数がもう1つあります。


1
注:このメソッドは、(setq uniquify-buffer-name-style 'forward)名前が付けられたバッファがある場合users\index.html(既に別のバッファがあるためposts\index.html)名前の変更が失敗する場合の意味と互換性がありません
dolzenko

(set-buffer-modified-p nil)不要のようです。rename-file-and-buffer変更されたバッファーを呼び出してからそれを強制終了しようとした場合、保存されていない変更について警告せずに喜んでそれを行います。
roldugin 2013

この関数は、現在のバッファがファイルに関連付けられているかどうかを確認する前に(やや煩わしいことに)新しい名前を要求します(その場合は中止されます)。
Thomas

338

はい、diredモードでは次のことができます。

  • C-x d diredを開く
  • RET 現在のファイルのディレクトリを選択する
  • C-x C-jdired-jump現在のファイル名に、Diredで)
  • Rファイルの名前を変更します(またはdired-do-rename)。
  • q (名前を変更した)ファイルバッファーに戻る

名前の変更はシェルと同等ですが、mv開いているバッファも更新mvします。ファイルシステムのファイルのアクセス時間と変更時間は変更されません。


9
これは、現在のファイルの名前を直接変更するものではありません。
pupeno 2008

4
Cx bと元のバッファーに戻ります。Elisp関数を作成してそれを行うこともできますが、多くのキーストロークを保存することはできないと思います。
Chris Conway、

6
また、Cx bではなくCx kを押すと、元のバッファーに戻ることができます。
Yoo

32
C-x C-j私にとっては、デフォルトではバインドされていません。こうM-x load-library RET dired-x RET最初は、それがバインドされます。
ntc2 2013年

4
C-x C-jバインドされていない場合の別の選択肢はM-x dired-jump、初めて実行することです。自動的に読み込まれますdired-x(これによりC-x C-j、この時点から定義されます)。
Fernando Basso

120

完全を期すために、Emacsの「名前を付けて保存」機能、つまり開いているファイルのCx Cwに対する答えが得られると思ってこのページにアクセスする人もいるので、


Cx Cwまたはメニューを使用File > Save as...
Yoo

編集中のファイルは元のファイルであるため、「名前を付けて保存」することはできません。
asmeurer 2013年

11
@asmeurerあなたは間違っている!保存後、新しいファイルを編集します。
Joel G Mathew

3
繰り返しますが、なぜコメントに反対票を投じる機能がないのですか?
クマの友達、2014

7
おそらくasmeurerは、「編集していた[ファイル]は引き続き[存在する]ことを意味していました。」それで正しいですか?私はチェックしますが、私のコメントは却下できません、ははは。
ブレイディトレーナー2014年

25

私のお気に入りはMagnarsからのものです(emacs rocksスクリーンキャストの名声です)。

他の選択肢とは異なり、名前を最初から入力する必要はありません。現在の名前を変更する必要があります。

(defun rename-current-buffer-file ()
  "Renames current buffer and file it is visiting."
  (interactive)
  (let* ((name (buffer-name))
        (filename (buffer-file-name))
        (basename (file-name-nondirectory filename)))
    (if (not (and filename (file-exists-p filename)))
        (error "Buffer '%s' is not visiting a file!" name)
      (let ((new-name (read-file-name "New name: " (file-name-directory filename) basename nil basename)))
        (if (get-buffer new-name)
            (error "A buffer named '%s' already exists!" new-name)
          (rename-file filename new-name 1)
          (rename-buffer new-name)
          (set-visited-file-name new-name)
          (set-buffer-modified-p nil)
          (message "File '%s' successfully renamed to '%s'"
                   name (file-name-nondirectory new-name)))))))

正しいバージョンのJames Yangに感謝します。


これは正しく機能していません。これはファイルの最後に「/」を追加します。
mythicalcoder

2
投稿してくれてありがとう。SOの方法は、回答を修正することであり、新しく修正されたものを投稿することではありません。
Unfun Cat 2017

15

これがsteveyから採用されたより堅牢なバージョンです。

;; Originally from stevey, adapted to support moving to a new directory.
(defun rename-file-and-buffer (new-name)
  "Renames both current buffer and file it's visiting to NEW-NAME."
  (interactive
   (progn
     (if (not (buffer-file-name))
         (error "Buffer '%s' is not visiting a file!" (buffer-name)))
     ;; Disable ido auto merge since it too frequently jumps back to the original
     ;; file name if you pause while typing. Reenable with C-z C-z in the prompt.
     (let ((ido-auto-merge-work-directories-length -1))
       (list (read-file-name (format "Rename %s to: " (file-name-nondirectory
                                                       (buffer-file-name))))))))
  (if (equal new-name "")
      (error "Aborted rename"))
  (setq new-name (if (file-directory-p new-name)
                     (expand-file-name (file-name-nondirectory
                                        (buffer-file-name))
                                       new-name)
                   (expand-file-name new-name)))
  ;; Only rename if the file was saved before. Update the
  ;; buffer name and visited file in all cases.
  (if (file-exists-p (buffer-file-name))
      (rename-file (buffer-file-name) new-name 1))
  (let ((was-modified (buffer-modified-p)))
    ;; This also renames the buffer, and works with uniquify
    (set-visited-file-name new-name)
    (if was-modified
        (save-buffer)
      ;; Clear buffer-modified flag caused by set-visited-file-name
      (set-buffer-modified-p nil)))

  (setq default-directory (file-name-directory new-name))

  (message "Renamed to %s." new-name))

良いですね。私のfunctions.elで身も凍るようになりました。
フェリックスD.

11

これは別のバージョンで、かなり堅牢でVCに対応しています。

(defun rename-file-and-buffer ()
  "Rename the current buffer and file it is visiting."
  (interactive)
  (let ((filename (buffer-file-name)))
    (if (not (and filename (file-exists-p filename)))
        (message "Buffer is not visiting a file!")
      (let ((new-name (read-file-name "New name: " filename)))
        (cond
         ((vc-backend filename) (vc-rename-file filename new-name))
         (t
          (rename-file filename new-name t)
          (set-visited-file-name new-name t t)))))))

詳細については、こちらをご覧ください



4

非常に簡単な方法は、コマンドを押し、ありはMxとタイプよりも、VC-名前変更・ファイルを使用すると、ディレクトリだけであなたの現在のファイルを選択する必要があり、新しい名前を選ぶよりも、その後、。変更されたファイルがあるバフが更新されます。

出典:https : //www.gnu.org/software/emacs/manual/html_node/emacs/VC-Delete_002fRename.html


1
これには、バージョン管理にコミットされる古いファイルと新しいファイルを追加するという(必ずしも望ましいとは限りません)副作用があります。しかし、+ 1は組み込み関数を使用して(主に)OPの質問に答えるためです。
恐竜

3

magnarsバージョンに基づいて、以下のように変更し、INITファイル名の部分を修正しました。

(defun rename-current-buffer-file ()
  "Renames current buffer and file it is visiting."
  (interactive)
  (let* ((name (buffer-name))
        (filename (buffer-file-name))
        (basename (file-name-nondirectory filename)))
    (if (not (and filename (file-exists-p filename)))
        (error "Buffer '%s' is not visiting a file!" name)
      (let ((new-name (read-file-name "New name: " (file-name-directory filename) basename nil basename)))
        (if (get-buffer new-name)
            (error "A buffer named '%s' already exists!" new-name)
          (rename-file filename new-name 1)
          (rename-buffer new-name)
          (set-visited-file-name new-name)
          (set-buffer-modified-p nil)
          (message "File '%s' successfully renamed to '%s'"
                   name (file-name-nondirectory new-name)))))))

これは良いです。上記のmagnarsバージョンは正しく機能していません。最後に「/」文字を追加します
mythicalcoder

-1

コピーで実現できます。ファイルでshift + cを押すと、emacsはファイル名を含むパスの名前を示すように要求するので、新しい名前を入力して入力するだけです...もちろん、以前の名前を削除する必要があります。


1
diredモードで "C"を参照しているようですが?これは、ファイルの名前を変更するのではなく、ファイルをコピーすることです(@ChrisConwayが指摘したように)これはdiredで "R"を使用して行われます。さらに、OPは現在のバッファーの名前の変更を要求しました。
Davor Cubranic、2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.