ในบัฟเฟอร์ที่หมดอายุให้วางจุดบนไฟล์ที่สำคัญที่สุดของไดเร็กทอรีนั้น


14

90% ของเวลาที่ฉันเยี่ยมชมไดเรกทอรีใน Emacs สิ่งแรกที่ฉันทำคือย้ายจุดไปยังไฟล์ที่เฉพาะเจาะจงและเปิด หลายครั้งที่ไฟล์ที่ฉันต้องการเปิดสามารถคาดเดาได้มาก ตัวอย่างเช่น

  • หากมีไฟล์ในไดเรกทอรีนี้ผมมักจะตรงไปที่.texmaster.tex
  • ที่รากของโครงการ Android AndroidManifest.xmlก็ทั่วไป
  • ในไดเรกทอรีที่ฉันพัฒนาแพ็คเกจ emacs มันมักจะเป็นไฟล์หลักของแพ็คเกจ ปกติแล้วจะเป็น.elไฟล์เดียวเท่านั้นในไดเรกทอรีนี้

มีวิธีที่ฉันจะสามารถวางจุดบนไฟล์เหล่านี้โดยอัตโนมัติเมื่อฉันเปิดไดเรกทอรีเหล่านี้หรือไม่?

นี้จะให้ความสะดวกสบายมาก (เพราะฉันสามารถเปิดได้โดยเพียงกดปุ่มRET) แต่ก็ยังให้ความยืดหยุ่นในการเยี่ยมชมไฟล์อื่น ๆ

คำตอบ:


16

dired-initial-position-hookเขียนฟังก์ชั่นที่กำหนดเองสำหรับ ในฟังก์ชั่นนี้คุณสามารถใช้ฟังก์ชั่นที่หลากหลายเพื่อค้นหาไฟล์และในที่สุดก็โทรdired-goto-fileเพื่อย้ายจุดไปยังไฟล์“ ดีที่สุด”:

(defun my-dired-goto-important-file ()
  "Go to an important file in the current dired buffer."
  (unless (bound-and-true-p save-place)
    (let ((candidates '("master.tex" "AndroidManifest.xml"))
          candidate)
      (while (and candidates
                  (not (dired-goto-file (expand-file-name (pop candidates)))))
        nil))))

(add-hook 'dired-initial-position-hook #'my-dired-goto-important-file)

ในต่อไปนี้ฉันจะอธิบายแง่มุมที่เฉพาะเจาะจงของฟังก์ชั่นนี้และเน้นส่วนขยายที่เป็นไปได้

ข้ามไปยังไฟล์

dired-goto-fileส่งคืนnilหากไฟล์ไม่มีอยู่ในบัฟเฟอร์ dired ปัจจุบันดังนั้นจึงปลอดภัยที่จะเรียกโดยไม่ตรวจสอบก่อน แต่dired-goto-fileต้องมีแน่นอนชื่อไฟล์ (ข้อผิดพลาดมันในชื่อญาติ) expand-file-nameจึง

กำลังค้นหาไฟล์

Dired ไม่ได้จัดทำ API ตรงไปข้างหน้าเพื่อค้นหาไฟล์ โดยทั่วไปคุณสามารถวนซ้ำไฟล์ทั้งหมดเช่นเดียวกับที่คุณวนซ้ำทุกบรรทัดในบัฟเฟอร์:

(let (files)
  (goto-char (point-min))
  (while (not (eobp))
    (let ((filename (dired-get-filename nil 'no-error)))
      (when filename
        (push filename files)))
    (forward-line 1))
  ;; Now `files' is a list of files, which you can search for patterns
  ;; …
  )

อย่างไรก็ตามมันสะดวกกว่าในการใช้ฟังก์ชั่นการทำเครื่องหมาย เพียงใช้ความระมัดระวังในการใช้อักขระเครื่องหมาย“ ผิดปกติ” เพื่อไม่ให้หลุดเครื่องหมายการโต้ตอบที่มีอยู่:

(unwind-protect
    (when (dired-mark-files-regexp (rx ".tex" string-end) ?t)
      (dired-goto-file (expand-file-name "master.tex")))
  (dired-unmark-all-files ?t))

บันทึกโหมดสถานที่

คุณต้องระมัดระวังเกี่ยวกับโหมดบันทึกสถานที่ในกรณีที่คุณเปิดใช้งาน ในบัฟเฟอร์ Dired โหมดบันทึกตำแหน่งจะไม่จดจำค่าจุดเช่นเดียวกับในโหมดอื่น ๆ แต่จะเปิดใช้ชื่อจุดสุดท้ายของไฟล์ เรียกคืนชื่อไฟล์นี้เหมือนที่เราทำ: มันเชื่อมโยงdired-initial-position-hookและเรียกdired-goto-file(ในความเป็นจริงนั่นคือที่ที่ฉันขโมยรหัสจาก :))

หากเบ็ดของเรามาก่อนบันทึกสถานที่โหมดบันทึกสถานที่จะแทนที่ตำแหน่งของเราโดยไม่มีเงื่อนไข อย่างไรก็ตามหากมาก่อน hook ของเรา (เช่นกรณีที่ Save Place ถูกเปิดใช้งานหลังจากที่คุณติดตั้ง hook นี้) ฟังก์ชั่นของเราจะเขียนทับ Save Place ซึ่งไม่ต้องการ อย่างไรก็ตามเช่นเดียวกับในบัฟเฟอร์ใด ๆ Save Place จะตั้งค่าตัวแปรโลคัลเป็นค่าsave-placeที่ไม่ใช่ศูนย์ดังนั้นเราจึงสามารถตรวจสอบได้และเพียงทำหน้าที่ Save Place ไม่ได้เรียกคืนชื่อไฟล์

หากคุณต้องการให้ Save Place“ หลวม” ให้ลบเครื่องหมายsave-placeออกและตรวจสอบให้แน่ใจว่า hook ของเราทำงานหลังจาก Save Place โดยเปิดใช้โหมด Save Place ก่อนแล้วจึงโทรadd-hookด้วยค่าที่ไม่ใช่ศูนย์สำหรับAPPENDอาร์กิวเมนต์


คำตอบที่ดี bound-and-true-pคุณอาจต้องการที่จะกำหนด :-)
Malabarba

@Malabarba เป็นในตัวแมโครจากbound-and-true-p bindings.el
Lunaryorn

พระเจ้าที่รักฉันไม่ได้ทำให้ฉันรู้สึกแย่ลงความจริงที่ฉันไม่รู้นั่นก็คือความจริงที่ฉันไม่รู้
Malabarba

@ Malabarba ไม่เป็นไรฉันใช้เวลาหนึ่งปี (ตามตัวอักษร) ในการค้นหาการมีอยู่ของฟังก์ชันนี้
Lunaryorn

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