เกิดอะไรขึ้นกับ `find-file-noselect`


11

ในคำตอบล่าสุดโดยLunaryornเขากล่าวว่า:

อย่างไรก็ตามฉันขอแนะนำให้เทียบกับส่วนอื่น ๆ ขององค์กรด้วยเหตุผลตามที่ระบุไว้ในความคิดเห็น: เก่าและเต็มไปด้วยวิธีปฏิบัติที่เป็นมรดกและเป็นอันตราย (เช่น find-file-noselect เพื่ออ่านไฟล์ที่ไม่มีการโต้ตอบ)

ทุกคนสามารถอธิบายได้หรือไม่ว่าทำไมจึงเป็นfind-file-noselectความคิดที่ดีที่จะอ่านไฟล์ในโปรแกรม Elisp มีวิธีที่ดีกว่า? ฉันถามเพราะฉันคิดว่าจะใช้มันในหนึ่งในโครงการของฉัน


ดูเหมือนไม่มีgood-practicesแท็กมาก่อน เป็นความคิดที่ดีที่จะใช้หรือไม่
mbork

ฉันคิดว่าgood-practicesมันจะตกอยู่ภายใต้หมวดหมู่ของ "เมตาแท็ก" ซึ่งถูกขมวดคิ้วโดย SE
nispio

1
@nispio ฉันคิดว่ามันเป็นแท็กที่ถูกต้อง แต่เราสามารถนำเมตานี้ไปใช้แน่นอน
Malabarba

1
@nsipio: ฉันได้อ่านบทความนี้แล้วและฉันไม่เห็นด้วย แต่ไม่ใช่ฉันที่ตัดสินใจ ;-)
mbork

คำตอบ:


14

TL; DR : ด้วยfind-file-noselectคุณมีการควบคุมไม่เกี่ยวกับสิ่งที่เกิดขึ้นจริงและคุณอาจจะจบลงด้วยโหมดเล็ก ๆ น้อย ๆ init.elโดยพลการเปิดใช้งานในบัฟเฟอร์ขึ้นอยู่กับสิ่งที่ผู้ใช้เปิดใช้งานในของพวกเขา นอกจากนี้การทำความสะอาดก็ยาก

ใช้with-temp-bufferและinsert-file-contentsแทน หากคุณต้องการโหมดใหญ่หรือรายย่อยที่เฉพาะเจาะจงในบัฟเฟอร์ที่ช่วยให้พวกเขาอย่างชัดเจน ในการเขียนไฟล์ให้ใช้with-temp-fileแทนซึ่งแม้จะมีชื่อของมันก็ช่วยให้คุณสามารถเขียนไฟล์ต่าง ๆ ได้

ผลข้างเคียง

find-file-noselectมีผลข้างเคียงมากมายรวมถึง

  • การถามคำถามแบบโต้ตอบ
  • เปิดใช้งานโหมดดูโดยอัตโนมัติสำหรับไฟล์แบบอ่านอย่างเดียว
  • เข้าสู่โหมดปกติมิฉะนั้น
  • find-file-hookและทำงาน

โหมดปกตินั้นเอง

  • เลือกโหมดหลักที่เหมาะสมสำหรับบัฟเฟอร์ปัจจุบันโดยอัตโนมัติ
  • รัน hooks โหมดหลักและรองที่สอดคล้องกันทั้งหมด
  • และอ่านตัวแปรโลคัลทั้งหมดสำหรับบัฟเฟอร์ปัจจุบันเช่นตัวแปรไฟล์และตัวแปรไดเร็กทอรีซึ่งอาจถามคำถามแบบโต้ตอบเกี่ยวกับตัวแปรโลคัลที่ไม่ปลอดภัย

เนื่องจากมีการเรียกใช้ hooks ทั้งหมดคุณจะได้รับโหมดรองทั้งหมดและฟังก์ชั่น hookที่ผู้ใช้เปิดใช้งานinit.elซึ่งอาจทำให้ทุกอย่างจากความไม่สะดวกเล็กน้อย (หากเปิดใช้งานโหมดรองที่ไม่พึงประสงค์) ถึงความเสียหายหลัก (หากผู้ใช้เพิ่มฟังก์ชัน hook ที่คาดว่า ถูกเรียกจากบริบทเชิงโต้ตอบ)

ดูhttps://github.com/flycheck/flycheck/issues/366สำหรับตัวอย่าง การใช้find-file-noselectไฟล์ข้อมูลทำให้เกิดการตรวจสอบไวยากรณ์โดย Flycheck และเนื่องจากมันเกิดขึ้นที่การปิดระบบของ Emacs จึงไม่มีเวลาที่จะทำความสะอาดอีกครั้งโดยทิ้งไฟล์ชั่วคราวไว้ข้างหลัง

ทำความสะอาด

ด้วยfind-file-noselectคุณจะต้องระมัดระวังเป็นพิเศษในการฆ่าบัฟเฟอร์อีกครั้ง find-file-noselectไม่ได้ทำเพื่อคุณ

คุณต้องจำบัฟเฟอร์ในบางสถานที่และใช้อย่างระมัดระวังunwind-protectเพื่อให้แน่ใจว่าบัฟเฟอร์ถูกฆ่าแม้ว่าในกรณีที่ไม่ได้อยู่ในระบบ

ทางเลือก

หากต้องการอ่านไฟล์ให้ใช้with-temp-bufferและinsert-file-contentsทำสิ่งพื้นฐานที่สุดเท่านั้นเช่นการแปลงระบบโค้ด แต่ไม่ถามคำถามเปิดใช้ hooks หรือตั้งค่าตัวแปรโลคอล:

(with-temp-buffer
  (insert-file-contents (locate-user-emacs-file "foo.el"))
  ;; Enter the major mode explicitly
  (emacs-lisp-mode)
  ;; …
  )

with-temp-buffer ใช้ความระมัดระวังเพื่อฆ่าบัฟเฟอร์ชั่วคราวที่ส่วนท้ายของร่างกาย

ในการเขียนไฟล์ให้ใช้with-temp-fileซึ่งสร้างบัฟเฟอร์ชั่วคราวและเขียนเนื้อหาไปยังชื่อไฟล์ที่กำหนดที่ส่วนท้ายของเนื้อหา:

(with-temp-file  (locate-user-emacs-file "foo.el")
  (prin1 (list 'my 'data) (current-buffer)))

10

จากส่วน 24.3 ในคู่มือ Elisp:

insert-file-contentsคัดลอกเนื้อหาของไฟล์ลงในบัฟเฟอร์ให้ใช้ฟังก์ชั่น (อย่าใช้คำสั่งinsert-fileในโปรแกรม Lisp ตามที่กำหนดเครื่องหมาย)

การค้นหาเอกสาร Elisp find-file-noselectนั้นชัดเจนว่ามันทำมากกว่าการอ่านไฟล์ลงในบัฟเฟอร์ บางทีคนที่คิดว่าใช้งานฟังก์ชั่นนี้เป็นความคิดที่ไม่ดีกำลังคิดเกี่ยวกับผลข้างเคียงที่อาจไม่เป็นที่ต้องการหรือไม่? ฉันเดาว่ามันขึ้นอยู่กับสิ่งที่คุณต้องการบรรลุ หากคุณต้องการที่จะมีเนื้อหาบัฟเฟอร์สะอาด / แตะต้องเป็นไปได้ว่ามันอาจจะเป็นความคิดที่ดีที่จะใช้เก่าและเชื่อถือwith-temp-buffer+ insert-file-contentsรวมกัน หากคุณต้องการเนื้อหาบัฟเฟอร์ที่จะใกล้เคียงกับสิ่งที่find-fileผลิตบางทีคุณอาจไม่ต้องการที่จะใช้งานfind-file-noselect? หรือบางทีเขากำลังคิดเกี่ยวกับfind-file;)


3
หากสิ่งที่จะถูกดำเนินการที่ไม่โต้ตอบฉันไม่สามารถเห็นสถานการณ์ใด ๆ ในที่ที่คุณต้องการ"เนื้อหาบัฟเฟอร์จะใกล้เคียงกับสิ่งที่พบไฟล์จะผลิต" find-file นั้นช้าเพราะมันมีสิ่งที่ไม่จำเป็นมากมายรวมถึง hooks ทุกประเภท "คุณสมบัติ" เดียวของไฟล์ค้นหาที่คุณอาจต้องการคือโหมดหลัก แต่จากนั้นคุณควรเปิดใช้งานด้วยตนเอง (คุณไม่สามารถรับประกันได้ว่าไฟล์ค้นหาจะเปิดโหมดที่คุณต้องการอยู่แล้ว)
Malabarba

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