Chức năng hiển thị đường dẫn đầy đủ của tệp hiện tại trong bộ đệm nhỏ


98

Tôi cần lấy đường dẫn đầy đủ của tệp mà tôi đang chỉnh sửa bằng emacs.

  • Có một chức năng cho điều đó?
  • Nếu không, hàm elisp sẽ là gì để có được điều đó?
  • Làm cách nào để sao chép kết quả (tên đường dẫn) vào khay nhớ tạm để tôi có thể sử dụng lại nó?

Tôi đang sử dụng Mac OS X và Aqumacs.

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

THÊM

(định nghĩa show-file-name ()
  "Hiển thị tên tệp đường dẫn đầy đủ trong bộ đệm nhỏ."
  (tương tác)
  (tin nhắn (đệm-tệp-tên))
  (kill-new (file-truename buffer-file-name))
)
(global-set-key "\ C-cz" 'show-file-name)

Kết hợp hai câu trả lời mà tôi nhận được, tôi có thể có được những gì tôi muốn. Cảm ơn vì những câu trả lời. Và một số câu hỏi khác.

  • Đối với (file-truename) là gì?
  • Tôi có thể sao chép tên đường dẫn vào khay nhớ tạm của Hệ thống (HĐH), không phải vòng đệm để tôi có thể sử dụng thông tin với các ứng dụng khác không?

Câu trả lời:


91

Đó là chức năng tích buffer-file-namehợp cung cấp cho bạn đường dẫn đầy đủ của tệp của bạn.

Điều tốt nhất cần làm là để cửa sổ emacs của bạn luôn hiển thị tên hệ thống của bạn và đường dẫn đầy đủ của bộ đệm mà bạn hiện đang chỉnh sửa:

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

Bạn cũng có thể làm điều gì đó như sau:

(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
Trong emacs 24 buffer-file-namelà một biến
barracel

5
... nhưng cũng vẫn là một chức năng
Phils

16
Nếu đó là một hàm thì tại sao nó không xuất hiện trong M-x?
asmeurer

8
asmeurer - bởi vì nó không tương tác
Ben Fitzgerald

2
@Talespin_Kit Đúng vậy. Elisp là "lisp-2" trái ngược với "lisp-1", có nghĩa là có hai không gian tên độc lập (biến và hàm). Do đó, mỗi biểu tượng có một "vị trí chức năng" và "vị trí giá trị", và vị trí nào được truy cập tùy thuộc vào ngữ cảnh. Có rất nhiều ví dụ trong thực tế (ví dụ: bất kỳ tên chế độ nhỏ nào sẽ vừa là hàm vừa là biến). Đây cũng là lý do tại sao bạn cần sử dụng những thứ thích funcallđể gọi một hàm được lưu trữ dưới dạng giá trị của một biến foo, bởi vì nếu bạn sử dụng, (foo)bạn sẽ sử dụng vùng chức năng foothay vì vùng giá trị.
phils

73

Để mượn câu trả lời của Jérôme Radix, nếu bạn chỉ muốn xem nhanh đường dẫn tệp của bộ đệm hiện tại, bạn có thể làm M-: buffer-file-name.

Hoặc, gõ (buffer-file-name)vào bộ đệm ở đâu đó và chạy C-x C-etrên dấu ngoặc đóng (điều này sẽ hoạt động ở bất kỳ chế độ nào, không chỉ ở chế độ lisp).


3
Cảm ơn, tôi nghĩ buffer-file-namenhư một chức năng, nhưng nó không xuất hiện trong M-x, nhưng xuất hiện trong M-:khi emacs eval, ở đó tôi có thể chạy lệnh, nhờ vào câu trả lời của bạn :)
PeterZD

6
Vâng, M-xchỉ chạy các chức năng tương tác, trong khi M-:chạy bất kỳ chức năng elisp nào.
asmeurer

40

Mẹo của tôi là làm C-x C-fnhư mở một tệp, nó sẽ điền trước minibuff bằng đường dẫn tệp hiện tại, C-gđể thoát. Nhanh hơn M-: buffer-file-namenhưng xấu hơn nhiều so với bất kỳ phương pháp nào khác.


Tôi cũng làm điều này. Nó không phải là khó như emacs-y nhưng nếu tất cả những gì tôi quan tâm là đường dẫn đến tệp hiện tại, thì nó hoạt động.
andrunix

Nếu bạn mở một tệp, nói A, sau đó chuyển sang tệp khác, nói B, ví dụ: sử dụng một số chức năng nhảy tới định nghĩa của một plugin, phương pháp này hiển thị đường dẫn của A, không phải B! Do đó, câu trả lời này không phải lúc nào cũng cung cấp những gì OP đang yêu cầu.
Abhishek Anand

4
Cx Cv sẽ chỉ cho bạn không chỉ là đường dẫn hiện tại nhưng tên tập tin hiện tại của cũng
kuzzooroo

@kuzzooroo phù hợp với người dùng không có chế độ ido (Tên được hiển thị trong Cx Cf với bạn sử dụng chế độ ido).
Julien Palard

16

Việc thực hiện trực tiếp những gì bạn muốn là:

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

Điều đó nói rằng, tôi thấy nó vô cùng hữu ích khi có thể có được đường dẫn đầy đủ của những gì có trong bộ đệm nhỏ và đây là những gì tôi sử dụng:

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

Và sau đó nếu tôi muốn nó trong clipboard, tôi chỉ cần ngắt dòng ( C-a C-k). Nhưng chúng ta có thể dễ dàng sao chép truename vào khay nhớ tạm trong lệnh trên, chỉ cần thay đổi dòng cuối cùng thành:

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

Phần mới là lệnh gọi 'kill-newđặt chuỗi vào vòng tiêu diệt.


Bạn có thể giải thích cách sử dụng cài đặt này không? Và "\ Cr" có nghĩa là gì?
modeller

Đừng bận tâm. Tôi đã hiểu rồi. Tôi nghĩ rằng nó rất hữu ích khi tôi ở chế độ ido và trỏ đến một tệp, sau đó tôi chỉ cần nhấn Cr để lấy đường dẫn đầy đủ của tệp đó. Quả thực hữu ích. Tuy nhiên tôi vẫn không biết lý do tại sao sử dụng \ C thay vì C.
modeller

11

Không cần thêm chức năng, chỉ cần

M-! pwd

Mặc dù điều này có thể hoạt động, nó sẽ không hoạt động trên hệ thống Windows và nó không giải thích được thực tế là thư mục làm việc hiện tại của emacs có thể khác với thư mục của tệp bộ đệm hiện tại. Bạn có thể tự mình thấy điều này bằng cách truy cập tệp có C-x C-f, đang chạy M-! pwd, sau đó M-x cdvà chọn một thư mục khác, sau đó chạy M-! pwdlại.
josaphatv

3

Tôi có mã sau đây đã được sử dụng trong một thời gian dài. Nó sao chép đường dẫn tệp đầy đủ vào vòng đệm khi tôi nhấn nút chuột giữa vào tên bộ đệm trong dòng chế độ. Nó chỉ sao chép tên bộ đệm vào vòng đệm khi tôi nhấn shift-mouse-2 vào tên bộ đệm trong dòng chế độ.

(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, cũng có thể gọi qua M-x list-directory, sẽ hiển thị cho bạn thư mục cho tệp hiện tại của bạn và bạn chỉ cần nhấn phím "Enter" để xóa bộ đệm nhỏ. Chi tiết bổ sung có sẵn tại đây .


câu trả lời yêu thích của tôi, đơn giản, nhanh chóng và dễ dàng!
ticktock

2

C-x C-b hiển thị danh sách các bộ đệm và đường dẫn tệp cho mỗi bộ đệm nếu có.


2

C-u C-x C-b liệt kê bộ đệm hiện đang truy cập tệp.


1

Tôi có thể sao chép tên đường dẫn vào khay nhớ tạm của Hệ thống (HĐH), không phải vòng đệm để tôi có thể sử dụng thông tin với các ứng dụng khác không?

Bạn có thể làm như vậy nếu bạn sử dụng một thứ gì đó như xclip (Linux), pbcopy (Mac), putclip (Cygwin).

Cá nhân tôi sử dụng các tập lệnh trình bao bọc cpđể sao chép và dán tương ứng, lần đọc đầu tiên từ đầu vào tiêu chuẩn, phần sau ghi vào đầu ra tiêu chuẩn. Bằng cách đó, điều này hoạt động trên tất cả các nền tảng phát triển của tôi:

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

Tôi thấy điều này đáng tin cậy và có thể định cấu hình hơn so với việc sử dụng hỗ trợ bảng tạm của Emacs. Ví dụ: clệnh của tôi sao chép đầu vào vào cả 3 khay nhớ tạm trên Linux (chính, phụ, khay nhớ tạm), vì vậy tôi có thể dán bằng Ctrl-V hoặc nhấp chuột giữa.


Điều này nên làm việc nhưng nó không cho tôi. Cụ thể là (Ubuntu 14.04.1.), date | xclipxclip filecả hai đều hoạt động như được quảng cáo (lưu trữ ngày tháng hoặc nội dung của tệp thành chính) nếu được nhập vào shell. Nhưng nếu tôi gõ một trong hai lệnh này sau M-! trong emacs (và hit return) không có gì xảy ra; con trỏ vẫn ở trong bộ đệm nhỏ như thể mong đợi nhiều đầu vào hơn; và nếu tôi ngắt để lấy lại quyền kiểm soát, không có hsas nào được lưu trữ trong chính.
Silvio Levy

Được rồi, ý tưởng của bạn hoạt động tốt với xsel thay vì xclip: (shell-command (format "echo '%s' | xsel -i" buffer-file-name))- và khi được tạo thành một lệnh tương tác (như được đề xuất trong câu trả lời được ủng hộ nhiều nhất bởi @JeromeRadix ở trên), đây là một CHIẾN THẮNG LỚN! Cảm ơn!
Silvio Levy

0

Cách đơn giản nhất và sẽ là

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

Vay mượn từ Trey Jackson, tôi nghĩ ra điều này:

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

Bạn có thể tìm thêm thông tin trên trang web


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.