จะเปลี่ยนองค์ประกอบของอลิสได้อย่างไร?


36

ฉันมีสิ่งนี้เป็นค่าเริ่มต้นในauto-mode-alist:

("\\.js\\'" . javascript-mode)

(ถึงกับemacs -Q) ฉันต้องการที่จะทดแทนสำหรับjs2-mode javascript-modeแน่นอนฉันสามารถใช้assq-delete-allแล้วadd-to-listอีกครั้ง แต่ฉันสงสัยว่าไม่มีวิธีที่ดีกว่า

แก้ไข: ฉันไม่ต้องการใช้ปรับแต่งอย่างชัดเจนฉันชอบการสร้างงานinit.elเอง

คำตอบ:


37

ในขณะที่คำตอบของ @ Dan เป็นคำตอบที่ดีมาก แต่ก็ไม่จำเป็น หนึ่งในเหตุผลที่ Emacs ใช้alistที่นี่เป็นที่ที่มี alist คุณก็สามารถเพิ่มองค์ประกอบใหม่ที่ด้านหน้าของรายการและมันจะเงาแมตช์ต่อไปลงรายการ

(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))

1
สนใจที่จะพูดว่าทำไม downvote
Drew

1
ฉันยกระดับคำตอบของคุณ - ขอบคุณดีที่รู้ ฉันเดาว่า downvoter คิดว่าวิธีนี้ไม่เหมาะสม (ฉันต้องบอกว่าฉันเห็นด้วยแม้ว่าจะไม่คิดว่ามันเป็นเหตุผลของการ downvoting - เพราะมันแก้ปัญหาของฉันและเป็นข้อมูลที่มีค่า!)
mbork

7
ยอมรับว่าไม่สามารถตอบคำถามของวิธีการแทนที่ ประเด็นคือคุณไม่จำเป็นต้องเปลี่ยน (เว้นแต่คุณมีความต้องการอื่นนอกเหนือจากที่คุณอธิบายไว้)
ดึง

2
คำถามไม่ได้จริงๆเกี่ยวกับการเปลี่ยนในความหมายทางเทคนิค แต่การเปลี่ยนแปลงในความรู้สึกที่ระดับสูงกว่า
Erik Allik

2
สิ่งนี้จะใช้งานได้เสมอไม่ว่าข้อเสียจะอยู่ในพื้นที่บริสุทธิ์หรือจะถูกลบออกในบางรุ่นในอนาคต
politza

33

ใช้setfเพื่อเปลี่ยนค่าในสถานที่:

(setf (cdr (rassoc 'javascript-mode auto-mode-alist)) 'js2-mode)

หากคุณต้องการแทนที่ค่าในรายการแสดงsetfว่าเครื่องจักรทั่วไปที่คุณต้องทำคือ สำหรับวิธีที่ใช้สำนวนมากขึ้นในการจัดการกับauto-mode-alistคำตอบให้ดูที่ @ Drew (และคำอธิบายของเขาเกี่ยวกับเงา)


ว้าว. ตอนนี้ฉันรู้สึกงี่เง่า ขอบคุณ! (และความคิดของ (เกือบ) ทุกสถานที่ที่จะsetfสามารถแสดงให้คนจาวาได้จริงๆ)
mbork

6
@mbork คุณอาจเพลิดเพลินไปกับคำอธิบายแบบคลาสสิกสำหรับผู้ชาย Perl lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html
purple_arrows

@mbork: จริงๆไม่มีเหตุผลที่จะรู้สึกโง่ ๆ - setfถูกใช้ตลอดเวลาใน Common LISP แต่คุณวิ่งข้ามมันบ่อยครั้งมากใน elisp
แดน

@ แดน: จริง ตอนนี้ผมกำลังสงสัยว่าทำไม Elisp ใช้setfจึงไม่ค่อยเมื่อเทียบกับ CL ...
mbork

19

วิธีที่เร็วที่สุดในการเปลี่ยนเซลล์ข้อเสียจริงอาจเป็นได้ setcdr

setcdr is a built-in function in `C source code'.

(setcdr CELL NEWCDR)

Set the cdr of CELL to be NEWCDR.  Returns NEWCDR.

มันน่าสังเกตว่าsetfไม่มีใน Emacsen รุ่นเก่า แต่setcdrเป็น


*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> (setq tmp '((one . 1) (two . 2) (three . 4)))
((one . 1)
 (two . 2)
 (three . 4))

ELISP> (setcdr (assq 'three tmp) 3)
3 (#o3, #x3, ?\C-c)
ELISP> tmp
((one . 1)
 (two . 2)
 (three . 3))

คุณรู้หรือไม่ว่า Emacs รุ่นsetfใดที่เพิ่มเข้ามา?
dshepherd

1
@dsheperd ไม่ใช่มือเปล่าไม่ ทำไมคุณต้องรู้ ฉันจะบอกว่า emac ใด ๆ ที่ควรตั้งเป้าหมายสำหรับการพัฒนาใหม่จะมี setf แต่อาจไม่มีการจัดการสำหรับข้อมูลประเภทที่คุณต้องการตั้งค่า พวกเขากำลังเรียกว่าตัวแปรทั่วไป
ฌอน Allred

ฉันอยากรู้ว่ามันดีไหมที่จะใช้ setf ในโค้ดใหม่บางอัน แต่อย่างที่คุณบอกว่ามันไม่มีตัวแปรทั่วไปสำหรับสิ่งที่ฉันต้องการจนกว่าจะมีเวอร์ชันล่าสุดอยู่ดี
dshepherd

5

OP ขอวิธีแก้ไขปัญหาที่จัดการกับรายชื่อที่มีคีย์สตริง เพื่อจัดการกับปัญหานั้นให้ดูคำถามนี้ หากบังเอิญคุณต้องจัดการกับเอลิสต์ด้วยปุ่มสัญลักษณ์จากนั้นใน Emacs 25 คุณสามารถใช้:

(setf (alist-get <key> <alist>) <value>)

เพื่อแทนที่ cdr หากคุณมีสิทธิ์เข้าถึง Emacs 26 เทคนิคนี้จะทำงานกับคีย์สตริงดังต่อไปนี้:

(setf (alist-get "\\.js\\'" auto-mode-alist nil nil #'equal) 'js2-mode)

โปรดทราบว่ามีวิธีอื่น ๆ ใน Emacs 26 เพื่อจัดการกับคีย์สตริง; ดูคำถามนี้ตามที่กล่าวไว้ข้างต้น


(setf (alist-get "\\.js\\'" auto-mode-alist nil nil #'equal) 'js2-mode)ควรทำงาน (ต้องใช้ Emacs 26)
npostavs

@RadonRosborough: มีฟีเจอร์แก้ไข พิจารณาที่จะแก้ไขคำตอบของคุณ
อันโตนิโอ

คุณกำลังใช้alist-getกับสตริง"\\.js\\'"แต่ alist-getเป็นไปตามassqดังนั้นมันจะไม่ทำงานกับสตริงตามที่คุณอ้างในคำตอบของคุณ
อันโตนิโอ

@antonio โอ้ใช่คุณถูกต้องทั้งหมด ฉันไม่ได้ตระหนักว่าคำถามที่โพสต์จริง ๆ แล้วต้องการโซลูชันที่จัดการกับคีย์สตริง ฉันจะแก้ไขขอขอบคุณ!
Radon Rosborough

2

หากคุณรู้ว่าคุณจะไม่ใช้ javascript-mode อีกเลยให้ auto-mode-alist ไม่ถูกแตะต้องและเพิ่มใน init.el ของคุณ

  (defalias 'javascript-mode 'js2-mode "Some handy explanation goes here.")

1
ที่จริงแล้วไม่มีjavascript-modeจริง ๆ : javascript-modeเป็นเพียงนามแฝงสำหรับjs-mode(โดยค่าเริ่มต้น) และมันทำด้วยวิธีนี้โดยเฉพาะเพื่อให้ผู้ใช้สามารถทำตามที่คุณแนะนำถ้าพวกเขาต้องการjs2-mode(โดยไม่สูญเสียความสามารถในการใช้js-modeถ้าพวกเขาต้องการ)
สเตฟาน

ฉันได้รับคำตอบจากนิสัยการใช้นามแฝงสำหรับโหมด cperl และ nxml-mode ดังนั้นเคล็ดลับที่นี่จะทำอย่างไร (defalias 'js-mode' js2-mode)?
Matthias

1
คุณเข้าใจฉันผิด. ฉันกำลังบอกว่าคำตอบของคุณถูกต้องและไม่ได้ป้องกันคุณจากการใช้ "javascript-mode" เนื่องจากสิ่งที่คุณโทรด้วยชื่อนั้นเป็นจริงjs-mode(ตรงกันข้ามกับสิ่งที่เกิดขึ้นperl-modeเป็นต้น)
สเตฟาน

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