Funkcja pokazująca pełną ścieżkę bieżącego pliku w mini buforze


98

Muszę uzyskać pełną ścieżkę do pliku, który edytuję za pomocą emacsa.

  • Czy jest do tego funkcja?
  • Jeśli nie, jaka byłaby funkcja elisp, aby to uzyskać?
  • Jak mogę skopiować wynik (nazwę ścieżki) do schowka, aby móc go ponownie wykorzystać?

Używam Mac OS X i Aqumacs.

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

DODANY

(defun nazwa-pliku-pokazu ()
  „Pokaż pełną nazwę pliku ścieżki w minibuforze”.
  (interaktywny)
  (wiadomość (nazwa-pliku-bufora))
  (kill-new (nazwa-pliku-pliku-bufora-nazwa-pliku))
)
(global-set-key "\ C-cz" 'show-file-name)

Łącząc dwie odpowiedzi, które otrzymałem, mogłem dostać to, czego chcę. Dzięki za odpowiedzi. I jeszcze kilka pytań.

  • Do czego służy (nazwa-pliku)?
  • Czy mogę skopiować nazwę ścieżki do schowka systemu (OS), a nie pierścień zabijania, aby móc używać tych informacji w innych aplikacjach?

Odpowiedzi:


92

Jest to wbudowana funkcja, buffer-file-namektóra podaje pełną ścieżkę do pliku.

Najlepszą rzeczą do zrobienia jest to, aby okno emacsa zawsze pokazywało nazwę systemu i pełną ścieżkę bufora, który aktualnie edytujesz:

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

Możesz też zrobić coś takiego:

(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

8
W buffer-file-name
emacsie

6
... ale także funkcja
phils

17
Jeśli jest to funkcja, dlaczego nie pojawia się w M-x?
asmeurer

9
asmeurer - ponieważ nie jest interaktywny
Ben Fitzgerald

2
@Talespin_Kit Tak, absolutnie. Elisp to „lisp-2” w przeciwieństwie do „lisp-1”, co oznacza, że ​​istnieją dwie niezależne przestrzenie nazw (zmienne i funkcje). Dlatego każdy symbol ma „gniazdo funkcyjne” i „gniazdo wartości”, a to, do którego gniazda uzyskuje się dostęp, zależy od kontekstu. W praktyce istnieje wiele przykładów (np. Dowolna nazwa trybu podrzędnego będzie zarówno funkcją, jak i zmienną). Jest to również powód, dla którego musisz użyć funkcji pokroju, funcallaby wywołać funkcję, która jest przechowywana jako wartość zmiennej foo, ponieważ gdybyś użył (foo), używałbyś fooraczej gniazda funkcji niż gniazda wartości.
phils

74

Aby pożyczyć z odpowiedzi Jérôme Radix, jeśli chcesz szybko zobaczyć ścieżkę pliku bieżącego bufora, możesz to zrobić M-: buffer-file-name.

Alternatywnie, wpisz (buffer-file-name)gdzieś bufor i uruchom C-x C-ew nawiasie zamykającym (zadziała to w każdym trybie, nie tylko w trybie lisp).


3
Dzięki, myślałem, że buffer-file-namejako funkcja, ale nie pojawia się M-x, ale pojawia się M-:jako emacs eval, tam mogę uruchomić polecenie, dzięki twojej odpowiedzi :)
PeterZD

6
Tak, M-xuruchamia tylko funkcje interaktywne, podczas gdy M-:uruchamia dowolną funkcję elisp.
asmeurer

41

Moja sztuczka polega na tym, aby zrobić coś C-x C-fpodobnego, aby otworzyć plik, C-gaby zakończyć minibuff bieżącą ścieżką do pliku . Szybszy niż, M-: buffer-file-nameale o wiele brzydszy niż inne metody.


Ja też to robię. To nie jest tak hardcore emacs-y, ale jeśli wszystko, na czym mi zależy, to ścieżka do bieżącego pliku, to działa.
andrunix

Jeśli otworzysz plik, powiedz A, a następnie skoczysz do innego pliku, powiedz B, np. Używając funkcji skoku do definicji wtyczki, ta metoda pokazuje ścieżkę A, a nie B! Dlatego ta odpowiedź nie zawsze zawiera to, o co prosi PO.
Abhishek Anand

4
Cx Cv pokaże nie tylko aktualną ścieżkę, ale także nazwę bieżącego pliku
kuzzooroo

@kuzzooroo, które jest odpowiednie dla użytkowników bez trybu ido (nazwa jest wyświetlana w Cx Cf, gdy używasz trybu ido).
Julien Palard

16

Bezpośrednia realizacja tego, co chcesz, to:

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

To powiedziawszy, uważam za niezwykle przydatne, aby móc uzyskać pełną ścieżkę tego, co jest w minibuforze, a tego używam:

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

A potem, jeśli chcę, żeby znalazła się w schowku, po prostu wyłączam linię ( C-a C-k). Ale moglibyśmy łatwo skopiować prawdziwą nazwę do schowka w powyższym poleceniu, po prostu zmień ostatnią linię na:

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

Nowa część to wywołanie, 'kill-newktóre umieszcza strunę w pierścieniu zabijania.


Czy możesz wyjaśnić, jak korzystać z tych ustawień? A co oznacza „\ Cr”?
modelarz

Nieważne. Rozgryzłem to. Myślę, że jest to przydatne, gdy jestem w trybie ido i wskazuję plik, a następnie po prostu naciskam Cr, aby uzyskać pełną ścieżkę do tego pliku. Rzeczywiście przydatne. Jednak nadal nie wiem, dlaczego używam \ C zamiast C.
modeller

11

Po prostu nie potrzebujesz dodatkowej funkcji

M-! pwd

Chociaż może to działać, nie będzie działać w systemach Windows i nie uwzględnia faktu, że bieżący katalog roboczy emacsa może różnić się od katalogu bieżącego pliku bufora. Możesz to zobaczyć na własne oczy, odwiedzając plik za pomocą C-x C-f, uruchamiając M-! pwd, a następnie M-x cdwybierając inny katalog i uruchamiając M-! pwdponownie.
josaphatv

3

Mam następujący kod w użyciu już od dłuższego czasu. Kopiuje pełną ścieżkę pliku do pierścienia zabijania, gdy naciskam środkowy przycisk myszy na nazwie bufora w wierszu trybu. Kopiuje tylko nazwę bufora do pierścienia zabijania, kiedy naciskam shift-mouse-2 na nazwę bufora w linii trybu.

(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, również wywoływany przez M-x list-directory, pokaże katalog dla twojego aktualnego pliku i wystarczy nacisnąć klawisz „Enter”, aby wyczyścić minibufor. Dodatkowe informacje dostępne są tutaj .


moja ulubiona odpowiedź, prosta, szybka i łatwa!
ticktock

2

C-x C-b pokazuje listę buforów i ścieżkę do pliku dla każdego bufora, jeśli ma to zastosowanie.



1

Czy mogę skopiować nazwę ścieżki do schowka systemu (OS), a nie pierścień zabijania, aby móc używać tych informacji w innych aplikacjach?

Możesz, jeśli wyskoczysz do czegoś takiego jak xclip (Linux), pbcopy (Mac), putclip (Cygwin).

Osobiście używam skryptów opakowujących coraz odpowiednio pdo kopiowania i wklejania, pierwszego odczytu ze standardowego wejścia, a drugiego zapisu na standardowe wyjście. W ten sposób działa to na wszystkich moich platformach programistycznych:

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

Uważam, że jest to bardziej niezawodne i konfigurowalne niż używanie obsługi schowka Emacsa. Na przykład moje cpolecenie kopiuje dane wejściowe do wszystkich 3 schowków w systemie Linux (podstawowy, dodatkowy, schowek), więc mogę wkleić za pomocą Ctrl-V lub kliknięcia środkowym.


To powinno działać, ale nie dla mnie. (Ubuntu 14.04.1.) Mianowicie, date | xclipi xclip fileoba działają zgodnie z zapowiedzią (przechowują datę lub zawartość pliku na podstawowym), jeśli zostaną wpisane w powłoce. Ale jeśli wpiszę którekolwiek z tych poleceń po M-! w emacs (i hit return) nic się nie dzieje; kursor pozostaje w minibuforze, jakby oczekiwał więcej danych wejściowych; a jeśli przerywam, aby odzyskać kontrolę, nic nie zostało zapisane w pierwotnym.
Silvio Levy

OK, twój pomysł działa dobrze z xsel zamiast xclip: (shell-command (format "echo '%s' | xsel -i" buffer-file-name)) - a kiedy zostanie przekształcony w komendę interaktywną (jak zasugerował @JeromeRadix powyżej), jest to WIELKA WYGRANA! Dzięki!
Silvio Levy

0

Najprostszy sposób i byłby

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

Pożyczając od Treya Jacksona, wymyśliłem to:

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

Więcej informacji można znaleźć na stronie


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.