ฉันควรรวมการเริ่มต้นที่ขี้เกียจที่ไหน?


13

ฉันต้องการเพิ่มคีย์เฉพาะการผูกกับโหมดลาเท็กซ์:

(define-key latex-mode-map (kbd "<f6>") 'my-latex-defun)

ในเวลาเดียวกันฉันต้องการตั้งค่าเฉพาะเมื่อโหลดโหมดเฉพาะ ดังนั้นฉันต้องการทราบว่ามีการตั้งค่า (แนวปฏิบัติที่ดีที่สุด) ระหว่างการใช้ hook ที่เหมาะสม ( latex-mode-hook) เพื่อให้บรรลุหรือใช้ clause (with-eval-after-load "tex-mode" ...เพื่อตัดคำจำกัดความการโยงคีย์ ฉันทดสอบทั้งคู่และทำงานได้ดี แต่ฉันสงสัยว่าอันไหนเป็นวิธีที่ถูกต้องที่จะทำ


2
with-eval-after-loadโหลดครั้งเดียวดังนั้นการเปลี่ยนคีย์แมปจะไปที่นั่น โหลด hooks ทุกครั้งที่มีการใช้งานโหมดเช่นเมื่อโหลดไฟล์ใหม่ที่เกี่ยวข้องกับโหมดหรือกำหนดเบ็ด คุณจะโหลดเช่นflyspell-modeหรือhl-line-modeในเบ็ด ในของinit.elฉันฉันใช้with-eval-after-loadประมาณ 160 ครั้งและadd-hook110 ครั้ง คนขี้เกียจเป็นผู้เริ่มต้นที่ดี (IMO)
rasmus

@rasmus ดูเหมือนคำตอบถ้าคุณมีเวลา :) ความแตกต่างของจำนวนครั้งที่รันโค้ดคือสิ่งสำคัญที่ต้องพิจารณาในความคิดของฉัน (เป็นเพียงคนเดียวที่ฉันสามารถนึกได้ ... )
Sean Allred

ด้วยเหตุนี้จึงเป็นความคิดที่ดีที่จะเปลี่ยนการเชื่อมโยงคีย์ในโหมด hooks ดูemacs.stackexchange.com/questions/990/…
ทาร์ซิอุส

คำตอบ:


18

การเริ่มต้นขี้เกียจคือการเริ่มต้นที่ดี

(IMO)

ควรใช้เมื่อไร with-eval-after-load

with-eval-after-loadถูกโหลดหนึ่งครั้งเมื่อคุณสมบัติหรือไฟล์บางอย่างถูกโหลดครั้งแรกดังนั้นการเปลี่ยนคีย์แมปจะเข้าไปในหนึ่งในเหล่านี้อย่างชัดเจน ไม่ใช่อย่างน้อยเพราะอาจไม่รู้จัก keymap ในเวลาเริ่มต้น [ลองอะไรทำนองนั้น(define-key message-mode-map (kbd "C-c f") 'Footnote-add-footnote)ในemacs -q] เบ็ดไม่ใช่คำตอบที่ดีเพราะมันผูกฟังก์ชั่นกับกุญแจทุกครั้งที่ตะขอเริ่มทำงาน ในฐานะที่เป็นบันทึกTarsiusคุณสามารถอ่านเพิ่มเติมเกี่ยวกับสาเหตุที่ไม่ควรlocal-set-keyอยู่ใน hooks

สุดท้ายให้สังเกตว่าwith-eval-after-loadGNU Emacs 24.4 เป็นเครื่องห่อหุ้ม 2 บรรทัดeval-after-loadที่bodyไม่จำเป็นต้องยกมา

เมื่อใช้ hooks

Hooks คือรายการฟังก์ชั่นที่โหลดทุกครั้งที่มีคุณสมบัติตรงตามเกณฑ์เช่นเริ่มโหมดบางโหมด ร่วมกันใช้ตะขอคือการโหลดเล็กน้อยโหมดเช่นหรือflyspell-mode เช่นhl-line-mode (add-hook 'org-agenda-mode-hook 'hl-line-mode)ในฐานะที่เป็นRémiชี้ให้add-hooksเป็นสมาร์ทและจะทำสิ่งที่ถูกต้องแม้ว่าตัวแปรเบ็ดยังไม่ได้รับการโหลด อย่างไรก็ตามฉันมีคำสั่งมากมายดังต่อไปนี้ซึ่งอาจเล็กน้อยสำหรับกำไรความเร็ว แต่ให้ความรู้สึกขององค์กรและโครงสร้างการพึ่งพา:

(with-eval-after-load 'org-agenda
  (add-hook 'org-agenda-mode-hook 'hl-line-mode))

ทำไมเพิ่มเบ็ดหลังจากorg-agenda? เช่นเคยC-h v org-agenda-mode-hook C-jส่งมอบ เบ็ดถูกกำหนดไว้ในตามที่แสดงในorg-agenda.el*help*

กำลังโหลดคุณสมบัติพิเศษ with-eval-after-load

with-eval-after-loadเป็นสิ่งสำคัญสำหรับการโหลดคุณสมบัติพิเศษ คุณอาจต้องการให้บางสิ่งเช่น(with-eval-after-load 'org (require 'org-inlinetask))โหลด org inlinetasks (find-library "org-inlinetask")เพื่อดูว่าทำไม ตั้งแต่org-inlinetasks.elโดยตรง(require 'org)ผู้autoloadดูแล Emacs ที่เป็นมิตรของคุณทุกคนใส่ใจอย่างมากที่จะให้ "ละเว้น" และorg.el(c)จะโหลดทั้งหมด

แต่ถ้าหาก (ส่วนตัว) ของคุณdefunจำเป็นต้องใช้หลายแห่ง หากคุณจู้จี้จุกจิกจริงๆคุณสามารถใส่defuns ในไฟล์อื่นในload-pathและเพิ่มautoloadคุกกี้หรือคุณสามารถบอก Emacs ว่าจะหาฟังก์ชั่นที่มีautoloadฟังก์ชั่น จากนั้นบางสิ่งเช่นนี้จะได้ผล:

(autoload 'org-cdlatex-mode "org" "cdlatex mode from org.")
(with-eval-after-load "latex"
  (add-hook 'TeX-mode-hook 'org-cdlatex-mode))

หรือคุณอาจrequire orgจะดึงมันออกมาcdlatex

และความจริงแล้วการท้าทายส่วนบุคคลจะไม่สำคัญมากนักสำหรับเวลาประทับส่วนใหญ่ 1,150 สายของการ defuns ส่วนตัว (84 defuns) ในของฉันinit.elเพิ่ม 0.02s มากกว่าวานิลลา Emacs

การวัดเวลาเริ่มต้น

วิธีที่ง่ายในการประมาณเวลาการกำหนดค่าเริ่มต้นคือ

time emacs --eval "(kill-emacs)"

emacs -q(มาตรฐานกับ

แต่เพื่อให้ได้รายละเอียดเพิ่มเติมโดยประมาณว่าจุดเริ่มต้นของปัญหาคอขวดเริ่มต้นที่ Joe Schafer esupหรือไม่

ในที่สุดเวลาโหลดไม่หายไปอย่างน่าอัศจรรย์ คุณจะผลักดันมันไปข้างหน้า (เพื่อขยายที่คุณใช้คุณสมบัติทั้งหมดในแต่ละเซสชั่น)


1
คุณไม่จำเป็นต้องใส่โปรแกรมเสริมลงใน with-eval-after-load เพราะ add-hook จะผูกตัวแปรถ้ายังไม่มี
Rémi

คุณพูดถูก! อาจจะยังมีการเพิ่มความเร็วจากมันได้หรือไม่? [ฉันจะพยายามอัปเดตคำตอบในภายหลังเพื่อสะท้อนสิ่งนี้]
rasmus

สิ่งที่เกี่ยวกับ defuns ที่ในภายหลังฉันต้องการที่จะผูกกับตะขอหรือการผูกกุญแจ ฉันควรกำหนด defun นอกwith-eval-after-loadโดยไม่สูญเสียข้อดีการเริ่มต้นขี้เกียจ?
jrbalderrama

5

นอกเหนือจากการแนะนำของคุณและการใช้เบ็ดให้ฉันแนะนำeval-after-load use-package.elคุณสามารถทำสิ่งที่คุณต้องการด้วย

(use-package latex
  :ensure auctex
  :bind ("<f6>" . my-latex-defun))

น้ำยางจะไม่สามารถโหลดจนกระทั่งหลังจากที่คุณร้องขอ

เช่นเดียวกับข้อความด้าน: การใช้ความระมัดระวังuse-packageทำให้เวลาเริ่มต้นของฉันลดลงเหลือไม่ถึงวินาที (ใช้เวลาประมาณสี่วินาที)


ขอบคุณสำหรับคำแนะนำของคุณ ฉันยังคิดที่จะใช้แพ็คเกจใช้ แต่ฉันอยากรู้ว่าจะทำยังไงโดยไม่มีแพ็คเกจเพิ่มเติม
jrbalderrama

1
@jrbalderrama note ที่use-packageถูกตั้งค่าให้จัดส่งพร้อม Emacs 25
Sean Allred
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.