ความแตกต่างระหว่าง setq และ setq-default ใน Emacs Lisp


89

ฉันมีคำถามเกี่ยวกับ Emacs Lisp setqและsetq-defaultต่างกันอย่างไร

บทช่วยสอนบอกว่าsetqมีผลในบัฟเฟอร์ในเครื่องในขณะที่setq-defaultมีผลกับบัฟเฟอร์ทั้งหมด

ตัวอย่างเช่นถ้าผมเขียน(setq A-var A-vars ค่า)ในinit.elผมพบว่าหลังจากที่เริ่มต้น Emacs และการเปิดกันชนใหม่ที่มี varยังมีและค่าที่เป็นความ vars มูลค่า ฉันคิดว่ามันไม่ควรจะอยู่ที่นั่น ดูเหมือนจะมีความแตกต่างระหว่างไม่มีsetqและsetq เริ่มต้น

มีอะไรผิดปกติกับความเข้าใจของฉัน?

ตัวอย่างเช่น:

  1. ฉันเขียน(setq hello 123)ในไฟล์init.elและเรียกใช้emacs abufferในเชลล์จากนั้นฉันป้อน"hello Cx Ce"มันจะแสดง "123" สิ่งเดียวกันนี้เกิดขึ้นเมื่อฉันเรียกใช้สิ่งนี้ในบัฟเฟอร์ใหม่ทั้งหมด

  2. ฉันเขียน(setq tab-width 4)ในไฟล์init.el เมื่อฉันเรียกใช้Cx Ce ที่มีความกว้างแท็บจะแสดง "8" (โหมดปัจจุบันคือ 'ข้อความ') อย่างไรก็ตามเมื่อฉันใช้(setq-default tab-width 4)มันจะแสดง "4" ฉันไม่สามารถอธิบายปรากฏการณ์นี้ได้

คำตอบ:


102

ตัวแปรบางตัวใน Emacs เป็น "buffer-local" ซึ่งหมายความว่าแต่ละบัฟเฟอร์ได้รับอนุญาตให้มีค่าแยกกันสำหรับตัวแปรนั้นที่แทนที่ค่าเริ่มต้นส่วนกลาง tab-widthเป็นตัวอย่างที่ดีของตัวแปรบัฟเฟอร์โลคัล

หากตัวแปรเป็นบัฟเฟอร์โลคัลให้setqตั้งค่าโลคัลในบัฟเฟอร์ปัจจุบันและsetq-defaultตั้งค่าเริ่มต้นส่วนกลาง

ถ้าตัวแปรไม่ได้เป็น buffer ท้องถิ่นแล้วsetqและsetq-defaultทำสิ่งเดียวกัน

ในกรณีของคุณ 2 (setq tab-width 4)ตั้งค่าบัฟเฟอร์ - โลคัลtab-widthเป็น 4 ในบัฟเฟอร์ปัจจุบันโดยปล่อยให้ค่าเริ่มต้นส่วนกลางtab-widthยังคงอยู่ที่ 8 ดังนั้นเมื่อคุณประเมินtab-widthในบัฟเฟอร์อื่นที่ไม่มีค่าโลคัลคุณจะเห็นว่า 8 จากนั้น เมื่อคุณตั้งค่าเริ่มต้นเป็น 4 บัฟเฟอร์นั้นจะหยิบมันขึ้นมาเนื่องจากยังไม่มีค่าในเครื่อง


เมื่อฉัน (ตั้งค่าความกว้างของแท็บ 4) และประเมินค่านั้นจะเป็น 8 เสมอในทุกบัฟเฟอร์ ฉันไม่รู้ว่าทำไม ดูเหมือนจะไม่มีผล แต่เมื่อฉันใช้ (set-default tab-width 4) จะมีผลในทุกบัฟเฟอร์ ฉันไม่รู้เหมือนกันว่าทำไม :(
ruanhao

(setq tab-width 4)มีผลในบัฟเฟอร์ที่คุณประเมินนิพจน์ หากคุณประเมินใน*scratch*บัฟเฟอร์ให้ตรวจสอบค่าในบัฟเฟอร์นั้น
tripleee

1
tab-widthเป็นตัวแปรบัฟเฟอร์โลคัล ดังนั้นเมื่อคุณ(setq tab-width 4)ตั้งค่าเป็น 4 ในบัฟเฟอร์ปัจจุบัน บัฟเฟอร์อื่น ๆ ทั้งหมดยังคงเป็นtab-widthค่าเริ่มต้นส่วนกลาง 8 เมื่อคุณ(setq-default tab-width 4)คุณกำลังเปลี่ยนค่าเริ่มต้นส่วนกลางtab-widthเป็น 4 ดังนั้นตอนนี้ทุกบัฟเฟอร์ที่ไม่ได้กำหนดtab-widthเองจะมีค่าเริ่มต้นใหม่
dfan

3
ใช่. ดูรายชื่อ emacs ฯลำดับของการกระทำที่เริ่มต้น การอ่านไฟล์ init คือขั้นตอนที่ 12 และการนำบัฟเฟอร์เริ่มต้นมาใช้คือขั้นตอนที่ 23
dfan

1
@ruanhao หากคุณ (setq tab-width 4) ใน init.el จะใช้กับบัฟเฟอร์นั้นเท่านั้น (init.el) หากคุณต้องการให้การเปลี่ยนแปลงนี้มีผลกับบัฟเฟอร์ใหม่ทั้งหมด (setq-default tab-width 4) จะทำให้สำเร็จ นอกจากนี้หากคุณต้องการสร้างโหมดสำหรับไฟล์บางประเภทคุณอาจต้องใช้ (setq tab-width 4) เพื่อไม่ให้แทนที่ค่าเริ่มต้นส่วนกลาง
Hemm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.