Функція показувати повний шлях поточного файлу в міні-буфері


98

Мені потрібно отримати повний шлях до файлу, який я редагую за допомогою emacs.

  • Чи є для цього функція?
  • Якщо ні, якою буде функція elisp для отримання цього?
  • Як я можу скопіювати результат (ім'я шляху) в буфер обміну, щоб я міг використовувати його повторно?

Я використовую Mac OS X та Aqumacs.

(setq filepath (get-fullpath-current-file)) ???
(copy-to-clipboard 'filepath) ???

ДОБАВЛЕНО

(defun show-file-name ()
  Msgstr "Показувати повне ім'я файлу шляху в мінібуфері."
  (інтерактивний)
  (повідомлення (буфер-ім'я файлу))
  (kill-new (file-truename buffer-file-name))
)
(global-set-key "\ C-cz" 'show-file-name)

Поєднуючи дві відповіді, які я отримав, я міг отримати те, що хочу. Дякую за відповіді. І ще кілька питань.

  • Для чого (ім'я файлу-ім’я)?
  • Чи можу я скопіювати ім'я шляху до буфера обміну системи (ОС), а не кільця вбивства, щоб я міг використовувати інформацію з іншими програмами?

Відповіді:


91

Саме вбудована функція buffer-file-nameдає повний шлях до вашого файлу.

Найкраще зробити, щоб у вашому вікні emacs завжди було вказано ім’я системи та повний шлях буфера, який ви зараз редагуєте:

(setq frame-title-format
      (list (format "%s %%S: %%j " (system-name))
        '(buffer-file-name "%f" (dired-directory dired-directory "%b"))))

Ви також можете зробити щось подібне:

(defun show-file-name ()
  "Show the full path file name in the minibuffer."
  (interactive)
  (message (buffer-file-name)))

(global-set-key [C-f1] 'show-file-name) ; Or any other key you want

7
В emacs 24 buffer-file-nameє змінна
barracel

5
... але також все ще є функцією
phils

16
Якщо це функція, то чому вона не відображається M-x?
асмеурер

8
asmeurer - тому що це не інтерактивно
Бен Фіцджеральд

2
@Talespin_Kit Так, абсолютно. Elisp - це "lisp-2" на відміну від "lisp-1", тобто є два незалежних простору імен (змінні та функції). Отже, кожен символ має "слот функції" та "слот значення", і доступ до якого слота залежить від контексту. На практиці є безліч прикладів (наприклад, будь-яке другорядне ім’я режиму буде одночасно функцією та змінною). Ось чому вам потрібно використовувати подібні символи funcallдля виклику функції, яка зберігається як значення змінної foo, тому що, якби ви використовували, (foo)ви б використовували слот функції, fooа не слот значення.
філ

73

Позичити у відповіді Jérôme Radix, якщо ви просто хочете швидко побачити шлях до поточного буфера файлу, ви можете зробити це M-: buffer-file-name.

Крім того, (buffer-file-name)десь введіть буфер і запустіть C-x C-eдужки, що закриваються (це буде працювати в будь-якому режимі, а не лише в режимі lisp).


3
Дякую, я думав, що buffer-file-nameце функція, але вона не відображається у M-x, а відображається M-:як emacs eval, там я можу запустити команду, завдяки вашій відповіді :)
PeterZD

6
Так, M-xвиконує лише інтерактивні функції, тоді як M-:запускає будь-яку функцію elisp.
asmeurer

40

Мій фокус полягає в тому, щоб зробити C-x C-fлайк, щоб відкрити файл, він попередньо заповнить minibuff поточним шляхом C-gдо файлу, щоб вийти. Швидше, ніж M-: buffer-file-nameнабагато потворніше, ніж будь-які інші методи.


Я теж це роблю. Це не такий хардкорний emacs-y, але якщо все, що мене цікавить, це шлях до поточного файлу, це працює.
andrunix

Якщо ви відкриваєте файл, скажімо A, а потім переходите до іншого файлу, скажімо B, наприклад, використовуючи деяку функцію переходу до визначення плагіна, цей метод показує шлях A, а не B! Таким чином, ця відповідь не завжди пропонує те, про що вимагає ОП.
Абхішек Ананд

4
Cx Cv покаже вам не просто поточний шлях, а й ім'я поточного файлу
kuzzooroo

@kuzzooroo - це правильно для користувачів, які не користуються ідо-режимом (ім'я відображається в Cx Cf, коли ви використовуєте ідо-режим)
Жульєн Палард

16

Безпосередня реалізація того, що ви хочете:

(defun copy-full-path-to-kill-ring ()
  "copy buffer's full path to kill ring"
  (interactive)
  (when buffer-file-name
    (kill-new (file-truename buffer-file-name))))

Зважаючи на це, мені здається неймовірно корисним мати можливість отримати повний шлях того, що є у minibuffer, і ось що я використовую:

(define-key minibuffer-local-completion-map "\C-r" 'resolve-sym-link)
(defun resolve-sym-link ()
  "Try to resolve symbolic links into true paths."
  (interactive)
  (beginning-of-line)
  (let* ((file (buffer-substring (point)
                                 (save-excursion (end-of-line) (point))))
         (file-dir (file-name-directory file))
         (file-true-dir (file-truename file-dir))
         (file-name (file-name-nondirectory file)))
    (delete-region (point) (save-excursion (end-of-line) (point)))
    (insert (concat file-true-dir file-name))))

І тоді, якщо я хочу це в буфер обміну, я просто вбиваю рядок ( C-a C-k). Але ми легко зможемо скопіювати справжнє ім'я в буфер обміну у вищевказаній команді, просто змінимо останній рядок на такий:

(insert (kill-new (concat file-true-dir file-name)))))

Нова частина - це виклик, до 'kill-newякого рядок потрапляє в кільце вбивства.


Чи можете ви детальніше описати, як використовувати ці налаштування? А що означає "\ Cr"?
модельєр

Не звертай уваги. Я зрозумів це. Я вважаю, що це корисно, коли я перебуваю в режимі ідо і вказую на файл, тоді я просто натискаю Cr, щоб отримати повний шлях до цього файлу. Справді корисно. Однак я досі не знаю, чому використовують \ C замість C.
модельєр

11

Не потрібно додаткової функції, просто

M-! pwd

Хоча це може працювати, воно не буде працювати в системах Windows, і це не враховує той факт, що поточний робочий каталог emacs може відрізнятися від каталогу поточного файлу буфера. Ви можете переконатися в цьому самі, відвідавши файл із C-x C-f, запустивши M-! pwd, а потім M-x cdвибравши інший каталог, а потім запустивши M-! pwdзнову.
josaphatv

3

У мене такий код вже використовується давно. Він копіює повний шлях до файлу до кільця вбивства, коли я натискаю середню кнопку миші на імені буфера в рядку режиму. Він копіює лише ім'я буфера в кільце вбивства, коли я натискаю shift-mouse-2 на ім'я буфера в рядку режиму.

(defun copy-buffer-file-name (event &optional bufName)
  "Copy buffer file name to kill ring.
If no file is associated with buffer just get buffer name.
"
  (interactive "eP")
  (save-selected-window
    (message "bufName: %S" bufName)
    (select-window (posn-window (event-start event)))
    (let ((name (or (unless bufName (buffer-file-name)) (buffer-name))))
      (message "Saved file name \"%s\" in killring." name)
      (kill-new name)
      name)))

(define-key mode-line-buffer-identification-keymap [mode-line mouse-2] 'copy-buffer-file-name)
(define-key mode-line-buffer-identification-keymap [mode-line S-mouse-2] '(lambda (e) (interactive "e") (copy-buffer-file-name e 't)))

3

C-x C-d, також дзвонить через M-x list-directory, покаже вам каталог вашого поточного файлу, і вам потрібно лише натиснути клавішу "Enter", щоб очистити мінібуфер. Додаткові відомості доступні тут .


моя улюблена відповідь, проста, швидка та легка!
галочка

2

C-x C-b показує список буферів та шлях до файлу для кожного буфера, де це можливо.



1

Чи можу я скопіювати ім'я шляху до буфера обміну системи (ОС), а не кільця вбивства, щоб я міг використовувати інформацію з іншими програмами?

Ви можете, якщо ви передаєте щось на зразок xclip (Linux), pbcopy (Mac), putclip (Cygwin).

Я особисто використовую обгорткові сценарії cта pдля копіювання та вставлення відповідно, перше читання зі стандартного вводу, друге написання на стандартний вихід. Таким чином, це працює на всіх моїх платформах розробки:

(shell-command (format "echo '%s' | c" buffer-file-name))

Я вважаю це більш надійним і налаштованим, ніж використання підтримки буфера обміну Emacs. Наприклад, моя cкоманда копіює введені дані у всі 3 буфера обміну в Linux (основний, вторинний, буфер обміну), тому я можу вставити їх за допомогою Ctrl-V або середнього клацання.


Це має спрацювати, але це не для мене. (Ubuntu 14.04.1.) А саме, date | xclipі те , і xclip fileінше працює так, як рекламується (зберігаючи дату або вміст файлу до первинного), якщо набрано в оболонці. Але якщо я наберу одну з цих команд після M-! в emacs (і натиснути return) нічого не відбувається; курсор залишається в мінібуфері, ніби очікуючи більше введення; і якщо я перерваю, щоб відновити контроль, нічого не зберігається в первинному.
Сільвіо Леві

Добре, ваша ідея чудово працює з xsel замість xclip: (shell-command (format "echo '%s' | xsel -i" buffer-file-name))- і коли вона перетворюється на інтерактивну команду (як запропоновано у найголоснішій відповіді @JeromeRadix вище), це ВЕЛИКИЙ ВИГОР! Дякую!
Сільвіо Леві

0

Найпростіший спосіб і буде

(buffer-name)<(C-x)(C-e)> for the file name to appear in the echo area

(buffer-name)<(C-u)(C-x)(C-e)> would print the location <here>

Позичаючи у Трі Джексона, я придумав таке:

(defun buffer-kill-path ()
  "copy buffer's full path to kill ring"
  (interactive)
  (kill-new (buffer-file-name)))

Ви можете знайти більше інформації на сайті


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.