Emacs에서 열린 파일의 이름을 바꾸려면 어떻게해야합니까?


237

Emacs에서 열린 파일의 이름을 바꾸는 방법이 있습니까? 내가 보는 동안? 다른 이름으로 저장과 같은 것이지만 원래는 사라져야합니다.

답변:


88

Steve Yegge의 .emacs 에서이 기능을 사용해보십시오 .

;; 출처 : http://steve.yegge.googlepages.com/my-dot-emacs-file
(데님 이름 바꾸기 파일 및 버퍼 (새 이름)
  "현재 버퍼와 NEW-NAME을 방문하는 파일의 이름을 모두 바꿉니다."
  (대화식 "새 이름 :")
  ((((이름 (버퍼-이름)))
        (파일 이름 (버퍼 파일 이름)))
    (파일 이름이 아닌 경우)
        ( "버퍼 '% s'이 (가) 파일을 방문하지 않습니다!"메시지)
      (만약 (get-buffer new-name)
          ( " '% s'버퍼가 이미 존재합니다!"메시지)
        (프론
          (이름 바꾸기 파일 이름 new-name 1)
          (버퍼 이름 변경)
          (방문 파일 이름 new-name)
          (버퍼 수정 -p nil))))))))

해당 페이지를 살펴보면 "move-buffer-file"이라는 또 다른 유용한 관련 기능이 있습니다.


1
참고 :이 메서드는 (setq uniquify-buffer-name-style 'forward)이름이 지정된 버퍼가 users\index.html이미있는 경우 버퍼 posts\index.html이름이
바뀌면

(set-buffer-modified-p nil)불필요한 것 같습니다. rename-file-and-buffer수정 된 버퍼 를 호출 한 후 종료하려고 시도하면 저장되지 않은 변경 사항에 대한 경고없이 기꺼이 수행합니다.
roldugin

이 함수는 또한 현재의 버퍼가 파일과 연관되어 있는지 (이 경우 중단됨) 확인 하기 전에 새로운 이름을 묻습니다 .
Thomas

338

예, dired모드를 사용하면 다음을 수행 할 수 있습니다.

  • C-x d 찢어지다
  • RET 현재 파일의 디렉토리를 선택
  • C-x C-j( dired-jump현재 파일 이름에 Dired로 표시)
  • R파일 이름을 바꿉니다 (또는 dired-do-rename).
  • q (이름이 바뀐) 파일 버퍼로 돌아가려면

이름 변경은 shell과 동일 mv하지만 열려있는 버퍼도 업데이트 mv하며 파일 시스템의 파일에 대한 액세스 및 수정 시간을 변경하지 않습니다.


9
현재 파일의 이름을 직접 바꾸지 않습니다.
pupeno December

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

4
C-x C-j언 바운드 경우 또 다른 대안 M-x dired-jump은 처음에 수행 하는 것입니다. 자동으로로드됩니다 dired-x( C-x C-j이 시점부터 정의됩니다).
페르난도 바쏘

120

완전성을 위해 일부 사람들은이 페이지를 방문하여 Emacs의 "다른 이름으로 저장"기능에 대한 답변을 얻을 것이라고 생각합니다. 즉, 열린 파일의 경우 Cx Cw입니다.


Cx Cw 또는 메뉴 사용File > Save as...
Yoo

편집중인 파일은 여전히 ​​원본 파일이므로 "다른 이름으로 저장"은 아닙니다.
asmeurer 2016 년

11
@asmeurer 당신이 틀 렸습니다! 저장하면 새 파일을 편집하게됩니다.
Joel G Mathew

3
다시 한 번 댓글을 내리는 기능이없는 이유는 무엇입니까?!
bearfriend

7
아마도 asmeurer는 "당신이 편집 한 파일은 여전히 ​​존재한다"는 것을 의미했을 것입니다. 그렇다면 맞습니까? 나는 확인 하겠지만, 당신은 내 의견을 공감할 수 없어, 하하하.
Brady Trainor

25

내가 가장 좋아하는 것은 Magnars ( emacs rock screencasts fame)의 것입니다.

다른 대안과 달리 처음부터 이름을 입력 할 필요가 없습니다. 현재 이름을 수정할 수 있습니다.

(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 방식은 약간 수정 된 새로운 답변을 게시하지 않고 답변을 수정하는 것입니다.
불행한 고양이

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

좋은데 이제 내 기능이 차가워집니다.
Felix 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-rename-file 유형보다 훨씬 쉬운 방법이 있습니다. 그런 다음 디렉토리에서 현재 파일을 선택하고 새 이름을 선택하면됩니다. 변경된 파일이있는 버프가 새로 고쳐집니다.

출처 : https://www.gnu.org/software/emacs/manual/html_node/emacs/VC-Delete_002fRename.html


1
이는 버전 제어에 커밋 할 이전 파일과 새 파일을 추가 할 때 바람직하지 않은 부작용이 있습니다. 그러나 +1은 내장 함수를 사용하여 OP의 질문에 (대부분) 대답하기 때문에 +1입니다.
공룡

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 버전이 제대로 작동하지 않습니다. 마지막에 "/"문자 추가
신화

-1

복사하여 얻을 수 있습니다. 파일에서 shift + c를 누르면 emacs는 파일 이름을 포함한 경로의 이름을 표시하도록 요청하므로 새 이름을 입력하고 입력하십시오. 물론 이전 이름을 삭제해야합니다.


1
dired 모드에서 "C"를 말하는 것 같습니까? 그것은 이름을 바꾸지 않고 파일을 복사하는 것입니다. 또한 OP는 현재 버퍼의 이름을 변경하도록 요청했습니다.
Davor Cubranic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.