เหตุใดฉันต้องเพิ่มแต่ละแพ็คเกจลงในโหลดพา ธ (หรือมีปัญหากับ 'แพ็คเกจในไฟล์ init ของฉัน)


17

ทุกครั้งที่ฉันติดตั้งแพคเกจจากเมนูแพคเกจถ้าฉันลองrequireมันในไฟล์ init ของฉันฉันจะได้รับข้อผิดพลาดยกเว้นว่าฉันจะเพิ่มมันลงในเส้นทางโหลดด้วยตนเอง:

(add-to-list 'load-path "/home/nick/.emacs.d/elpa/use-package-20141220.1645")

(require 'use-package-autoloads)
(require 'use-package)

นั่นน่าเบื่อ และโดยปกติเส้นทางแพคเกจประกอบด้วยหมายเลขรุ่น หากมีการอัปเดตแพ็คเกจฉันต้องแก้ไขเส้นทางโหลดด้วยตนเอง

มีวิธีใดที่จะทำให้สิ่งนี้เป็นแบบอัตโนมัติหรือไม่?

คำตอบ:


23

TL; DR:

เพิ่มบรรทัดต่อไปนี้ที่ด้านบนของไฟล์ init ของคุณ ( .emacs.d/init.elหรือ.emacs):

(package-initialize)

คำอธิบาย

การสร้างไฟล์เพิ่มเติมที่ Emacs อาจใช้เนื่องจากuser-init-fileไม่ใช่วิธีที่เหมาะสม เพราะคู่มือไม่ได้พูดซึ่งเป็นที่ต้องการในกรณีที่มีความขัดแย้งอย่างน้อยไม่ได้อยู่ในส่วนที่คุณยกมาทั้งหมดนี้ไม่สามารถที่จะเพิ่มความสับสน - ตอนนี้เราไม่ทราบว่าที่จริงคือuser-init-file(ซึ่งเป็นค่าที่คุณอาจต้องการ เพื่อตรวจสอบเพื่อค้นหา)

ดังนั้นเริ่มต้นด้วยการลบตัวเลือกทั้งหมดยกเว้น~/.emacs.d/init.elซึ่งเป็นที่ต้องการโดยทั่วไป (โดยผู้ใช้) เพราะมันไม่ได้มีส่วนทำให้เกิดความยุ่งเหยิงที่ไม่บริสุทธิ์$HOMEและช่วยให้สามารถเก็บไฟล์การกำหนดค่า Emacs ทั้งหมดรวมถึงไฟล์ที่สำคัญที่สุดภายใต้การควบคุมเวอร์ชัน Emacs

ตามค่าเริ่มต้นการเรียก Emacs package-initialize หลังจากโหลดไฟล์ init ของผู้ใช้แล้ว มันทำได้เลยเพราะปัจจุบันผู้ใช้ส่วนใหญ่ติดตั้งแพ็คเกจโดยใช้package.el- ดังนั้นพวกเขาไม่ควรทำอะไรเพื่อให้แพ็คเกจเหล่านี้พร้อมใช้งาน

ในทางกลับกันไม่ได้ทุกคนไม่ดังนั้นจึงควรจะเป็นไปไม่ได้package-initializeโทร การป้องกันไม่ให้มีการเรียกใช้ฟังก์ชันนั้นโดยการเพิ่ม(setq package-enable-at-startup nil)ลงในไฟล์เริ่มต้นของผู้ใช้ (คุณสามารถใส่ไว้ที่ไหน)

package-initializeไม่สามารถเรียกได้ก่อนที่ผู้ใช้จะมีการเปลี่ยนแปลงเพื่อแจ้งให้ Emac ไม่ต้องทำดังนั้นจึงต้องทำหลังจากโหลดไฟล์ init ตราบใดที่ผู้ใช้ติดตั้งแพ็กเกจแล้วใช้ตามที่เป็นอยู่หรือปรับแต่งโดยใช้อินเตอร์เฟสแบบกำหนดเองที่ทำงานได้ดี แต่ถ้าคุณต้องการปรับแต่งแพ็กเกจของคุณโดยใช้ elisp คุณต้องตรวจสอบให้แน่ใจก่อนว่ามันใช้งานได้จริงload-pathก่อนที่จะใช้ฟังก์ชั่นที่กำหนด

มันค่อนข้างง่ายที่จะทำและจัดทำเอกสารอย่างถูกต้อง (ถ้าฉันดูก่อนอื่นฉันไม่ต้องเขียนอะไรข้างต้น: - /

เหตุผลในการโหลดแพ็กเกจอัตโนมัติเกิดขึ้นหลังจากโหลดไฟล์ init คือตัวเลือกผู้ใช้จะได้รับค่าที่กำหนดเองหลังจากโหลดไฟล์ init เท่านั้นรวมถึงตัวเลือกผู้ใช้ที่มีผลต่อระบบบรรจุภัณฑ์ ในบางสถานการณ์คุณอาจต้องการโหลดแพ็กเกจอย่างชัดเจนในไฟล์ init ของคุณ (โดยปกติจะเป็นเพราะโค้ดอื่น ๆ ในไฟล์ init ของคุณขึ้นอยู่กับแพ็คเกจ) ในกรณีที่ไฟล์ init package-initializeของคุณควรเรียกใช้ฟังก์ชัน มันขึ้นอยู่กับคุณที่จะตรวจสอบให้แน่ใจว่าpackage-load-listมีการตั้งค่าตัวเลือกผู้ใช้ที่เกี่ยวข้องเช่น(ดูด้านล่าง) ก่อนการpackage-initializeโทร คุณควรตั้งค่า package-enable-at-startupเป็นnilเพื่อหลีกเลี่ยงการโหลดแพ็กเกจอีกครั้งหลังจากประมวลผลไฟล์ init หรือคุณอาจเลือกที่จะยับยั้งการโหลดแพ็กเกจโดยสมบูรณ์เมื่อเริ่มต้นและเรียกใช้คำสั่ง 'Mx package-initialize' เพื่อโหลดแพ็กเกจของคุณด้วยตนเอง

ดังนั้น:

;;; .emacs.d/init.el -- the `user-init-file'

(package-initialize)
(setq package-enable-at-startup nil)

(require 'use-package)

(use-package some-package
  :init (setq some-package-variable "foobar")

    ...

;;; .emacs.d/init.el ends here

แน่นอนว่าปัญหา (หรือปัญหาเพิ่มเติม) อาจเป็นเพราะการพิมพ์ผิดSymbol's function definition is void: use-packgeอยู่ในไฟล์ init ของคุณและจะไม่เกิดขึ้นจนกว่าคุณจะพิมพ์ลงใน emacs.se


1
ยังครอบคลุมถึงstackoverflow.com/questions/11127109/…
phils

มันใช้ได้หรือไม่(require 'use-package)ก่อนหน้านี้(package-initialize)?
陳力

3

ฉันคิดว่าafter-init-hookวิธีการแก้ปัญหาที่กล่าวถึงในคำตอบล้นกองนี้ควรจะกล่าวถึง:

(defun my-packages-init ()
  (require 'some-great-package))

(add-hook 'after-init-hook 'my-packages-init)

ฉันคิดว่านี่เป็นวิธีที่ควรจะทำ แต่คำตอบอื่น ๆ ให้ข้อมูลเกี่ยวกับวิธีอื่นในการทำ


0

ต่อไปนี้จะเพิ่ม dirs ทั้งหมดภายใต้~/.emacs.d/site-lispเส้นทางโหลดดังนั้นคุณสามารถเพียงแค่requireแพคเกจและคุณเสร็จแล้ว:

(let* ((my-lisp-dir "~/.emacs.d/site-lisp/")
       (default-directory my-lisp-dir)
       (orig-load-path load-path))
  (setq load-path (cons my-lisp-dir nil))
  (normal-top-level-add-subdirs-to-load-path)
  (nconc load-path orig-load-path))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.