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.