ความแตกต่างระหว่าง init และ config ในแพ็คเกจใช้งาน


16

ฉันมีการกำหนดค่าเช่นนี้:

(use-package html-mode
  :mode "\\.html\\'"
  :config
  (progn
    (add-hook 'html-mode-hook 'turn-off-auto-fill)))

ตอนนี้เมื่อฉันไปและเยี่ยมชมไฟล์ HTML ฉันสังเกตauto-fillว่าไม่ได้ปิดอยู่ แต่ถ้าผมใช้:initแทน:config, auto-fillรับปิด ดังนั้นคำถามของฉันคือเมื่อมีคำสั่งภายใต้:configดำเนิน?

คำตอบ:


16

พวกเขาจะแตกต่างกันถ้าแพคเกจถูกเลื่อนออกไปคือไม่ได้โหลดจนกว่าจะมีความจำเป็น ในกรณี:initนั้นจะถูกดำเนินการในเวลาที่ไฟล์ emacs ของคุณถูกอ่านครั้งแรก แต่:configจะถูกดำเนินการในเวลาที่มีการโหลดแพคเกจจริง

ในตัวอย่างของคุณการใช้modeimplersly defers โหลดแพ็กเกจ คุณได้กำหนดค่าแพคเกจที่จะโหลดในครั้งแรกที่มีการเยี่ยมชมไฟล์ html

คุณสามารถใช้:demandเพื่อให้แน่ใจว่าแพคเกจที่มีการโหลดเสมอที่เริ่มต้น :initแต่มีแนวโน้มที่สิ่งที่คุณต้องการจะทำที่นี่จะใส่เบ็ดของคุณ

จาก docstring:

:init Code to run when `use-package' form evals.

เนื่องจากคุณใส่สิ่งนี้ลงในไฟล์ผู้ใช้ init ของคุณนั่นหมายความว่ามันจะทำงานเมื่อเริ่มต้น

:config Runs if and when package loads.

ดังนั้นอย่ารันจนกว่าแพ็กเกจจะถูกโหลดจริง ..

:defer Defer loading of package -- automatic if :commands, :bind, :bind*,  :mode or :interpreter are used.

บันทึกรายการสิ่งต่าง ๆ ที่ทำให้แพคเกจถูกเลื่อนออกไปโดยอัตโนมัติ โดยทั่วไปถ้าคุณบอกuse-packageเงื่อนไขที่คุณต้องการแพคเกจนี้จะถือว่าคุณไม่ต้องการโหลดจนกว่าเงื่อนไขเหล่านั้นจะเกิดขึ้น

:demand Prevent deferred loading in all cases.

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

ปรับปรุง

การทบทวนนี้โดยอ้างอิงจากความคิดเห็นล่าสุด ... สิ่งที่ฉันพูดไว้ข้างต้นนั้นเป็นความจริง แต่ฉันคิดว่ามันไม่ถูกต้องที่จะตอบคำถาม ปัญหารากที่นี่เป็นจริงที่html-modeไม่ได้เป็นแพคเกจ sgml-modeแต่โหมดที่กำหนดโดยแพคเกจ ทำงานได้ตามที่คาดไว้สำหรับฉัน:

(use-package sgml-mode
  :mode ("\\.html\\'" . html-mode)
  :config (add-hook 'html-mode-hook 'turn-off-auto-fill))

ในตัวอย่างดั้งเดิม:configนิพจน์ไม่ได้รับการประเมินเนื่องจากแพ็กเกจที่ชื่อhtml-modeไม่ได้รับการโหลด การย้ายนิพจน์เหมือนเดิมเพื่อใช้:initงานได้เนื่องจากรหัสเริ่มต้นจะถูกประเมินเสมอโดยไม่คำนึงว่าแพ็กเกจจะได้รับการโหลดหรือไม่



@npostavs ขอบคุณมูลค่าการสังเกต ฉันยังไม่ได้ย้ายไปใช้แพ็คเกจ 2.0 สำหรับสิ่งหนึ่งฉันใช้งานได้:idleอย่างกว้างขวางและไม่ได้ตรวจสอบผลกระทบของ ": idle ถูกลบ"
ลูกัส

1
ฉันยังไม่เข้าใจว่าทำไมเมื่อเขาเข้าชมไฟล์ HTML และเรียกให้โหลดแพคเกจauto-fillไม่ปิดเช่นรหัสการกำหนดค่าไม่ทำงาน ผมมีปัญหาเดียวกัน.
Ken Williams

@KenWilliams ปัญหาของคุณอยู่กับ html-mode เช่นกัน? ฉันคิดว่าปัญหาที่แท้จริงของที่นี่html-modeคือไม่ใช่แพ็คเกจ อย่างน้อยในรุ่นปัจจุบันของฉัน Emacs, ถูกกำหนดไว้ในแพคเกจhtml-mode sgml-modeดังนั้นถ้าคุณบอกuse-packageให้ทำอะไรบางอย่างเมื่อมีการhtml-modeโหลดชื่อแพคเกจที่รหัสไม่เคยทำงานเพราะไม่มีแพคเกจดังกล่าวเคยโหลด คุณจะต้องใส่การตั้งค่าโหมด HTML (use-package sgml-mode ....)ใน
ลูกัส

ขออภัย - ปัญหาของฉันอยู่กับที่ไม่ได้org-mode html-modeปัญหาที่คล้ายกันมีที่แพคเกจที่เรียกว่าorg-modeแต่แพคเกจ ELPA orgเรียกว่า บางทีมันอาจทำให้สับสน (หรือฉัน)?
Ken Williams

7

ตัวอย่างเช่นนี้ทำให้ผมง่ายมากที่จะเข้าใจความแตกต่างระหว่างและ:init :configลองมาตัวอย่างของace-windowแพคเกจ (แต่อาจเป็นแพคเกจใด ๆ ) ใส่ไว้ในinit.elไฟล์ของคุณ:

(use-package ace-window
  :ensure t
  :defer t
  :config
  (progn
    (message "ace window: hello world")))

ตอนนี้เปิด emacs ของคุณและดูใน*Messages*บัฟเฟอร์เพื่อดูว่ามีhello worldข้อความใด ๆ คุณจะไม่สามารถค้นหาใด ๆ ได้เนื่องจากแพ็กเกจถูกเลื่อนออกไป ตอนนี้เปลี่ยนจากconfigเป็นinit:

(use-package ace-window
  :ensure t
  :defer t
  :init
  (progn
    (message "ace window: hello world")))

ตอนนี้ปิดและเปิด emacs ใหม่และตรวจสอบ*Messages*บัฟเฟอร์ คุณจะเห็นข้อความace window: hello worldเพราะรหัสจะทำงานไม่ว่า:initจะได้รับเมื่อใด ในกรณีของconfigมันจะทำงานเฉพาะเมื่อโหลดแพคเกจนั้น


ที่จะช่วยให้เพียงคำถามด้านสิ่งที่เป็นความแตกต่างแล้วระหว่างคำหลัก:initและ:prefaceขึ้นอยู่กับตัวอย่างของคุณหรือไม่
ปริญญาเอก

@Doctorate: :prefaceทำงานแม้ว่าแพคเกจที่มีปัญหาจะถูกปิดใช้งานแต่:initจะทำงานเฉพาะเมื่อเปิดใช้งานแพคเกจ
bbenne10
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.