Функция ELisp, чтобы разрешить переименование файла в Emacs


Как отказ от ответственности, это первая функция у меня когда-либо написанных на Лиспе или ELisp. Пожалуйста, колотить его так же, как и любой другой кусок, но не суди меня за это, пожалуйста! :)

Так, я понял, что я хотел способ переименовать файлы без нервотрепки открытие файла и т. д. Я погуглил и нашел функцию в https://stackoverflow.com/questions/384284/can-i-rename-an-open-file-in-emacs (кредитные Стив Yegge).

Однако, он, казалось, не хорошо работать с uniquify. Это было проблемой. Наличие двух открытых файлов и пытается переименовать первое имя второе (например CMakeLists.txt, что там может быть много) вызвал его на поруки, поскольку он только проверил имя буфера (который не был уникальным, но, как uniquify не делать это дело, прежде чем что-то должен uniquifying).

Единственный способ я нашел, чтобы заставить "ре-uniquification" был к закрытию предыдущего буфера и открыть новый файл. Это выглядит очень некрасиво...

(defun is-unique-name-for-buffer (new-name)
  (let ((file-name (buffer-file-name))
    (dir-name (file-name-directory buffer-file-name)))
  (let ((new-complete-name (concat dir-name new-name)))
  (progn (not (string-equal file-name new-complete-name))))))

(defun rename-file-and-buffer (new-name)
  "Renames both current buffer and file it's visiting to NEW-NAME."
  (interactive "sNew name: ")
  (let ((name (buffer-name))
    (filename (buffer-file-name))
    (dir-name (file-name-directory (buffer-file-name))))
    (if (not filename)
    (message "Buffer '%s' is not visiting a file!" name)
      (if (not (is-unique-name-for-buffer new-name))
      (message "A buffer named '%s' already exists in that location!" new-name)
    (progn
      (rename-file (file-name-nondirectory filename) new-name 1)
      (kill-buffer)
      (set-buffer (find-file (concat dir-name new-name))))))))


477
8
задан 6 октября 2011 в 08:10 Источник Поделиться
Комментарии
1 ответ

Решение цепей отключить; вам нечего бояться.

Я собирался предположить, что там должна быть функция, что вы можете позвонить, чтобы заставить uniquify буфер, но м-х кстати РЕТ ^уник не показывают каких-либо документированных функций, который будет делать это за вас (посмотрите и попытайтесь немного, если вам нравится, вы можете найти более элегантное решение).


Лисп (на самом деле, Elisp и общий Лисп; схема делает свое дело) Конвенции до конца предикатных функций С или П , а не начать их есть-.

(defun unique-name-for-buffer-p (new-name)
(let ((file-name (buffer-file-name))
(dir-name (file-name-directory buffer-file-name)))
(let ((new-complete-name (concat dir-name new-name)))
(progn (not (string-equal file-name new-complete-name))))))


Ваш предикат представляется раскроя пустьх только потому, что вам нужна новая-полное имя , чтобы обратиться к Дир-имя. Когда вы находитесь в такой ситуации, вы можете использовать вместо этого давайте*. Это так же, как пусть кроме того, что пункты, которые гарантированно будут оценены в порядке (это все-таки хороший стиль, чтобы использовать пусть , когда вы можете, но давайте* лучше, чем много вложенных давайтес).

(let* ((file-name (buffer-file-name))
(dir-name (file-name-directory buffer-file-name))
(new-complete-name (concat dir-name new-name)))
(progn (not (string-equal file-name new-complete-name))))


Вам нужно только явные progn , когда вы хотите оценить несколько выражений как один (вы используете его правильно, в ваших вложенных Если, но читайте дальше).

(defun unique-name-for-buffer-p (new-name)
(let* ((file-name (buffer-file-name))
(dir-name (file-name-directory buffer-file-name))
(new-complete-name (concat dir-name new-name)))
(not (string-equal file-name new-complete-name))))


Вложенные еслив вашей вторая функция может быть выражена как один Конд (который также помогает избавиться от что законных progn).

(defun rename-file-and-buffer (new-name)
"Renames both current buffer and file it's visiting to NEW-NAME."
(interactive "sNew name: ")
(let ((name (buffer-name))
(filename (buffer-file-name))
(dir-name (file-name-directory (buffer-file-name))))
(cond ((not filename)
(message "Buffer '%s' is not visiting a file!" name))
((not (unique-name-for-buffer-p new-name))
(message "A buffer named '%s' already exists in that location!" new-name))
(t (rename-file (file-name-nondirectory filename) new-name 1)
(kill-buffer)
(set-buffer (find-file (concat dir-name new-name)))))))

8
ответ дан 19 января 2012 в 03:01 Источник Поделиться