Вопрос или проблема
Одна из главных функций, по которым я скучаю в Vim, это то, что он всегда сохраняет имя текущего файла в буфере %
(больше информации). Это позволяет легко запускать команды, такие как:
;; компиляция текущего файла
:! gcc %
;; исходный код текущего файла (полезно, когда я редактирую .vimrc)
:source %
;; узнать размер текущего файла
:! du -sh %
;; и так далее...
Мне хотелось бы иметь аналогичную функциональность в emacs
(версия 24, если это имеет значение), а именно — иметь простой способ вставить имя файла, открытого в текущем буфере.
Примеры того, что я хочу сделать
Здесь я описываю некоторые базовые случаи использования, чтобы лучше объяснить, когда я чувствую необходимость в таком ярлыке
-
Компиляция: Когда я выбираю
M-x compile
, emacs спрашивает у меня команду компиляции. Мне хотелось бы просто ввестиgcc (current-buffer)
. -
Загрузка файла: Когда я редактирую свой .emacs файл, я хотел бы загрузить его тут же, чтобы протестировать изменения. Сейчас я делаю это командой
M-x load-file
и каждый раз вручную ввожу имя . e m a c s. Хотелось бы иметь ярлык. -
Запуск внешних процессов: я дал
du -sh
в качестве примера, только для иллюстрации того, что я хочу, чтобы ярлык также был доступен, когда я выполняю команды оболочки с помощьюM-!
Что я нашел до сих пор
- Этот вопрос здесь на U&L. Данные ответы в основном показывают, как найти имя файла из буфера, чтобы потом добавить его в потиринг. Это не совсем то, что я ищу; я не хочу вручную получать имя файла перед тем, как его использовать. (Также описанные в обеих ответах решения не работают у меня в emacs столь же плавно и требуют дополнительных нажатий клавиш, что делает их немного неудобными).
EDIT: Немного не по теме, но я выяснил, почему эти решения не работают. У меня включен IDO, к лучшему или к худшему.
- Функция
(current-buffer)
описанная в руководстве, действительно возвращает имя файла в текущем буфере, но ни в одном из приведенных выше примеров я не выполняю код elisp. Есть ли способ вставить результат выполнения этой функции в (мини)буфер и привязать это к ярлыку?
Я неправильно думаю об этом?
Я сейчас учусь использовать emacs (это уже несколько месяцев, на самом деле) после многих лет использования Vim. Я хочу избежать предсказуемой ловушки использовать-emacs-как-Vim. Если вы считаете, что то, что я прошу, не очень по-emacs, и должно быть лучшее (более чистое?) решение, пожалуйста, упомяните это в ваших ответах.
Вы можете вставить такую функцию в ваш .emacs
и привязать её к любой клавише по вашему выбору.
(defun insert-file-name ()
"Insert the full path file name into the current buffer."
(interactive)
(insert (buffer-file-name (window-buffer (minibuffer-selected-window)))))
Также смотрите этот вопрос, он кажется похожим.
Небольшой вариант ответа @easyb’s — вместо того, чтобы вставлять путь в буфер, скопируйте его в kill-ринг (полезно для файлов только для чтения):
(defun filename ()
"Copy the full path of the current buffer."
(interactive)
(kill-new (buffer-file-name (window-buffer (minibuffer-selected-window)))))
(kill-new buffer-filename)
кажется достаточным, если вы привяжете его к клавише таким образом — я добавил эту строку в мой ~/.emacs.d/init.el
:
(global-set-key (kbd "C-c w") (lambda () (interactive) (kill-new buffer-file-name)))
Когда я хочу поместить текущее имя файла в kill буфер, я просто нажимаю C-c w
, затем использую обычное C-y
в любом месте, где я хочу его вставить.
Хотя это не отвечает на вопрос напрямую, можно получить имя файла текущего буфера, выполнив dired-jump
(C-x C-j
), а затем w
.
.
Ответ или решение
Чтобы получить имя файла текущего буфера в Emacs, вы можете воспользоваться несколькими подходами, которые помогут выполнить задачи, аналогичные привычным вам по использованию Vim. Эмпирический опыт показывает, что, несмотря на обилие встроенных инструментов, иногда пользователь стоит перед необходимостью автоматизировать действия, такие как компиляция, загрузка файла или запуск внешних процессов.
Вставка имени файла текущего буфера
Для вставки полного пути текущего файла в буфер вы можете создать и использовать следующую функцию:
(defun insert-file-name ()
"Вставляет полное имя файла текущего буфера в текущий буфер."
(interactive)
(insert (buffer-file-name (window-buffer (minibuffer-selected-window)))))
Данную функцию можно связать с любой удобной клавишной комбинацией путем добавления следующего кода в ваш файл .emacs
:
(global-set-key (kbd "C-c i") 'insert-file-name)
Теперь, нажимая C-c i
, вы сможете вставить имя файла в буфер.
Копирование имени файла в kill-ring
Если цель состоит в том, чтобы скопировать путь файла в буфер обмена (kill-ring), можно использовать такую функцию:
(defun filename ()
"Копирует полное имя файла текущего буфера."
(interactive)
(kill-new (buffer-file-name (window-buffer (minibuffer-selected-window)))))
Эту функцию также можно связать с конкретной клавишной комбинацией, например:
(global-set-key (kbd "C-c w") 'filename)
Теперь, нажав C-c w
, вы можете скопировать имя файла в буфер обмена и использовать его с помощью команды C-y
(вставка).
Альтернативные подходы
-
dired-jump: Вы можете использовать команду
dired-jump
(C-x C-j
), чтобы перейти вdired
на текущий файл. Затем нажмитеw
, чтобы скопировать полный путь файла. -
Без использования функций: Если вам знаком Emacs Lisp, вы можете создать более сложные сценарии для своих нужд, например, автоматизировать загрузку
.emacs
файла или запуск внешних команд, интегрируя логику получения имени файла в макросы или пользовательские команды.
Эти подходы помогут вам добиться нужного функционала аналогично тому, каким образом вы использовали Vim, и в то же самое время опираются на богатые возможности автоматизации Emacs. Такой переход позволит вам оптимизировать рабочие процессы и подчеркнуть функциональную гибкость Emacs.