ฟังก์ชันแสดงพา ธ เต็มของไฟล์ปัจจุบันในมินิบัฟเฟอร์


98

ฉันต้องการเส้นทางแบบเต็มของไฟล์ที่ฉันแก้ไขด้วย emacs

  • มีฟังก์ชั่นสำหรับสิ่งนั้นหรือไม่?
  • ถ้าไม่ฟังก์ชั่น elisp ในการรับสิ่งนั้นคืออะไร?
  • ฉันจะคัดลอกผลลัพธ์ (ชื่อพา ธ ) ไปยังคลิปบอร์ดเพื่อนำกลับมาใช้ใหม่ได้อย่างไร

ฉันใช้ Mac OS X และ Aqumacs

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

เพิ่มแล้ว

(ยุติการแสดงชื่อไฟล์ ()
  "แสดงชื่อไฟล์พา ธ แบบเต็มในมินิบัฟเฟอร์"
  (เชิงโต้ตอบ)
  (ข้อความ (ชื่อไฟล์บัฟเฟอร์))
  (kill-new (ชื่อไฟล์บัฟเฟอร์ชื่อไฟล์))
)
(global-set-key "\ C-cz" 'แสดงชื่อไฟล์)

เมื่อรวมสองคำตอบที่ฉันได้ฉันจะได้สิ่งที่ต้องการ ขอบคุณสำหรับคำตอบ และคำถามอื่น ๆ

  • สำหรับ (file-truename) คืออะไร?
  • ฉันสามารถคัดลอกชื่อพา ธ ไปยังคลิปบอร์ดของ System (OS) ไม่ใช่ kill ring เพื่อใช้ข้อมูลกับแอพอื่นได้หรือไม่

คำตอบ:


93

เป็นฟังก์ชันในตัว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

8
ใน emacs 24 buffer-file-nameเป็นตัวแปร
barracel

6
... แต่ยังคงเป็นฟังก์ชัน
phils

18
ถ้ามันเป็นฟังก์ชั่นทำไมมันไม่ปรากฏในM-x?
asmeurer

9
asmeurer - เพราะมันไม่โต้ตอบ
Ben Fitzgerald

2
@Talespin_Kit ใช่แน่นอน Elisp เป็น "lisp-2" ซึ่งตรงข้ามกับ "lisp-1" ซึ่งหมายความว่ามีช่องว่างชื่ออิสระสองช่อง (ตัวแปรและฟังก์ชัน) แต่ละสัญลักษณ์จึงมี "ช่องฟังก์ชัน" และ "ช่องค่า" และช่องใดที่เข้าถึงได้ขึ้นอยู่กับบริบท มีตัวอย่างมากมายในทางปฏิบัติ (เช่นชื่อโหมดรองใด ๆ จะเป็นทั้งฟังก์ชันและตัวแปร) นี่คือเหตุผลที่คุณต้องใช้ไลค์ในfuncallการเรียกใช้ฟังก์ชันที่เก็บไว้เป็นค่าของตัวแปรfooเพราะถ้าคุณใช้(foo)คุณจะใช้ช่องฟังก์ชันfooแทนช่องค่า
Phils

74

หากต้องการยืมจากคำตอบของJérôme Radix หากคุณต้องการดูเส้นทางไฟล์ของบัฟเฟอร์ปัจจุบันอย่างรวดเร็วคุณสามารถทำได้ M-: buffer-file-nameถ้าคุณเพียงแค่ต้องการได้อย่างรวดเร็วเห็นเส้นทางแฟ้มของบัฟเฟอร์ปัจจุบันที่คุณสามารถทำได้

อีกวิธีหนึ่งพิมพ์(buffer-file-name)ในบัฟเฟอร์ที่ใดที่หนึ่งและเรียกใช้C-x C-eในวงเล็บปิด (ซึ่งจะทำงานในโหมดใดก็ได้ไม่ใช่แค่โหมดเสียงกระเพื่อม)


3
ขอบคุณฉันคิดว่าbuffer-file-nameเป็นฟังก์ชั่น แต่ไม่ปรากฏในM-xแต่ปรากฏในM-:ขณะที่emacs evalฉันสามารถเรียกใช้คำสั่งได้ขอบคุณคำตอบของคุณ :)
PeterZD

6
ใช่M-xเรียกใช้ฟังก์ชันแบบโต้ตอบเท่านั้นในขณะที่M-:เรียกใช้ฟังก์ชัน elisp ใด ๆ
asmeurer

41

เคล็ดลับของฉันคือทำC-x C-fเหมือนเปิดไฟล์มันจะเติมมินิบัฟด้วยเส้นทางไฟล์ปัจจุบันก่อนC-gเพื่อออก เร็วกว่าM-: buffer-file-nameแต่น่าเกลียดกว่าวิธีอื่น ๆ


ฉันก็ทำแบบนี้เหมือนกัน ไม่ใช่ emacs-y ที่ไม่ยอมใครง่ายๆ แต่ถ้าสิ่งที่ฉันสนใจคือเส้นทางไปยังไฟล์ปัจจุบันมันก็ใช้ได้
andrunix

หากคุณเปิดไฟล์ให้พูดว่า A แล้วข้ามไปยังไฟล์อื่นพูดว่า B เช่นใช้ฟังก์ชันการข้ามไปยังนิยามของปลั๊กอินวิธีนี้จะแสดงเส้นทางของ A ไม่ใช่ B! ดังนั้นคำตอบนี้ไม่ได้เสนอสิ่งที่ OP ขอเสมอไป
Abhishek Anand

5
Cx Cv จะไม่แสดงแค่พา ธ ปัจจุบัน แต่เป็นชื่อไฟล์ปัจจุบันด้วย
kuzzooroo

@kuzzooroo เหมาะสำหรับผู้ใช้ที่ไม่ใช่โหมด ido (ชื่อนี้แสดงใน Cx Cf โดยที่คุณใช้ ido-mode)
Julien Palard

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

ที่กล่าวว่าฉันพบว่ามันมีประโยชน์อย่างเหลือเชื่อที่จะได้รับเส้นทางที่สมบูรณ์ของสิ่งที่อยู่ในมินิบัฟเฟอร์และนี่คือสิ่งที่ฉันใช้:

(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) แต่เราสามารถคัดลอก truename ไปยังคลิปบอร์ดในคำสั่งด้านบนได้อย่างง่ายดายเพียงแค่เปลี่ยนบรรทัดสุดท้ายเป็น:

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

ส่วนใหม่คือการเรียก'kill-newที่ทำให้สตริงอยู่ในวงแหวนฆ่า


คุณสามารถอธิบายวิธีใช้การตั้งค่านี้อย่างละเอียดได้หรือไม่? และ "\ Cr" หมายถึงอะไร?
modeller

ไม่เป็นไร. ฉันคิดออกแล้ว ฉันคิดว่ามันมีประโยชน์เมื่อฉันอยู่ในโหมด ido และชี้ไปที่ไฟล์จากนั้นฉันก็แค่กด Cr เพื่อรับเส้นทางแบบเต็มของไฟล์นั้น มีประโยชน์จริง อย่างไรก็ตามฉันยังไม่รู้ว่าทำไมต้องใช้ \ C แทน C.
modeller

11

ไม่จำเป็นต้องมีฟังก์ชั่นพิเศษเพียง

M-! pwd

แม้ว่าจะสามารถใช้งานได้ แต่จะไม่ทำงานบนระบบ Windows และไม่สามารถอธิบายได้ว่าไดเร็กทอรีการทำงานปัจจุบันของ emacs อาจแตกต่างจากไดเร็กทอรีของไฟล์บัฟเฟอร์ปัจจุบัน คุณสามารถดูสิ่งนี้ได้ด้วยตัวคุณเองโดยไปที่ไฟล์ที่C-x C-fเรียกใช้M-! pwdจากนั้นM-x cdเลือกไดเร็กทอรีอื่นจากนั้นเรียกใช้M-! pwdอีกครั้ง
josaphatv

3

ฉันมีรหัสต่อไปนี้ใช้งานมานานแล้ว มันคัดลอกเส้นทางไฟล์แบบเต็มไปยัง kill ring เมื่อฉันกดปุ่มกลางของเมาส์ที่ชื่อบัฟเฟอร์ในบรรทัดโหมด มันคัดลอกเพียงชื่อบัฟเฟอร์ไปยัง kill-ring เมื่อฉันกด 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" เพื่อล้างมินิบัฟเฟอร์ รายละเอียดเพิ่มเติมมีอยู่ที่นี่


คำตอบที่ชื่นชอบง่ายรวดเร็วและง่ายดาย!
ticktock



1

ฉันสามารถคัดลอกชื่อพา ธ ไปยังคลิปบอร์ดของ System (OS) ไม่ใช่ kill ring เพื่อใช้ข้อมูลกับแอพอื่นได้หรือไม่

คุณสามารถถ้าคุณใส่บางอย่างเช่น xclip (Linux), pbcopy (Mac), putclip (Cygwin)

ฉันใช้สคริปต์ wrapper เป็นการส่วนตัว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 (และตีกลับ) ไม่มีอะไรเกิดขึ้น เคอร์เซอร์ยังคงอยู่ในมินิบัฟเฟอร์ราวกับว่าต้องการอินพุตเพิ่ม และถ้าฉันขัดจังหวะเพื่อให้สามารถควบคุมได้อีกครั้งจะไม่มีการจัดเก็บ hsas ไว้ในหลัก
Silvio Levy

ตกลงความคิดของคุณใช้ได้ดีกับ xsel แทนที่จะเป็น xclip: (shell-command (format "echo '%s' | xsel -i" buffer-file-name))- และเมื่อสร้างเป็นคำสั่งแบบโต้ตอบ (ตามที่แนะนำในคำตอบที่โหวตมากที่สุดโดย @JeromeRadix ด้านบน) นี่คือชัยชนะที่ยิ่งใหญ่! ขอบคุณ!
Silvio Levy

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>

ยืมมาจาก Trey Jackson ฉันคิดสิ่งนี้:

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

คุณสามารถค้นหาข้อมูลเพิ่มเติมได้ที่เว็บไซต์


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.