รีสตาร์ท emacs จากภายใน emacs


44

ฉันรีสตาร์ท emacs ของฉันมาก สิ่งที่ฉันต้องการทำคือสร้างฟังก์ชั่นที่ฆ่า emacs ปัจจุบันเพียงเพื่อวางไข่ใหม่เท่านั้น เป็นการดีที่จะทำงานใน TTY


8
ทำไมคุณถึงฆ่าและรีสตาร์ทบ่อย ๆ ทันที?
แดน

2
ฉันพัฒนาตัวเองอย่างแข็งขัน.emacs.dซึ่งหมายความว่าฉันจะรีสตาร์ท emacs เพื่อกำจัดขยะใด ๆ ที่ฉันได้ทำลายลงในสภาพแวดล้อมของฉัน มีอีกไม่กี่กรณีใช้งานที่ฉันทำเช่นนี้ แต่ที่ใหญ่ที่สุด
PythonNut

1
@PythonNut ฉันคิดว่าคุณจำเป็นต้องใส่คำถามใหม่อีกครั้ง คุณสามารถบอกbashให้รีสตาร์ทหลังจากยุติได้หรือไม่ หรือvi? หรือกระบวนการอื่นใดตามกฎ? ไม่เพราะนั่นอยู่นอกขอบเขตของข้อกังวลและได้รับการจัดการอย่างเหมาะสมจากภายนอก ไม่ว่าในกรณีใดสิ่งที่คุณต้องการจริงๆคือวิธีการกำหนดค่าemacs ใหม่โดยการล้าง VM และเรียกใช้รหัสเริ่มต้นของคุณอีกครั้ง ( โดยไม่ต้องฆ่ากระบวนการ) นั่นจะเป็นประโยชน์และเหมาะสมกับ emacs ฉันไม่รู้ว่ามันมีอยู่หรือไม่ :)
harpo

4
@harpo ใช่ฉันจะได้รับที่จะเริ่มต้นใหม่กับbash exec bashฉันไม่มีความคิดเกี่ยวกับกลุ่ม
PythonNut

11
FWIW ฉันมีแนวโน้มที่จะเริ่มต้นอินสแตนซ์ใหม่ของ Emacs เพื่อทดสอบการเปลี่ยนแปลงการกำหนดค่าแทนที่จะออกและเริ่มต้นใหม่ ทำไม? เพราะหากรหัสของฉันมีข้อผิดพลาด Emacs อาจไม่สามารถโหลดการตั้งค่าของฉันเมื่อฉันรีสตาร์ทและ ณ จุดนั้นฉันไม่สามารถรับอินสแตนซ์ที่ใช้งานจริงด้วยการตั้งค่าปกติของฉันดังนั้นฉันจึงต้องใช้การแก้ไขที่คุ้นเคยน้อยกว่า สภาพแวดล้อมในการแก้ไขข้อผิดพลาด มันจะไม่เกิดขึ้นบ่อยครั้ง แต่มันน่ารำคาญเมื่อมันเกิดขึ้น ฉันสามารถเรียกใช้emacs -qและแก้ไขปัญหาได้แน่นอน แต่ฉันต้องการให้อินสแตนซ์ "ดี" ทำงานอยู่ตลอดเวลาเมื่อแฮ็คการกำหนดค่าของฉันเพียงเพื่อความปลอดภัย
phils

คำตอบ:


25

หมายเหตุ: ผมห่อต่อไปนี้ในแพคเกจrestart-emacsที่มีอยู่ที่นี่


นี่เป็นอีกทางเลือกหนึ่งในการบรรลุสิ่งที่คุณต้องการโดยใช้อิลิทบริสุทธิ์ (ไม่ใช่จากการพึ่งพาเชลล์) เคล็ดลับคือการวางไข่ในกระบวนการอื่น emacs ก่อนที่ emacs ปัจจุบันจะถูกฆ่า

(defun launch-separate-emacs-in-terminal ()
  (suspend-emacs "fg ; emacs -nw"))

(defun launch-separate-emacs-under-x ()
  (call-process "sh" nil nil nil "-c" "emacs &"))

(defun restart-emacs ()
  (interactive)
  ;; We need the new emacs to be spawned after all kill-emacs-hooks
  ;; have been processed and there is nothing interesting left
  (let ((kill-emacs-hook (append kill-emacs-hook (list (if (display-graphic-p)
                                                           #'launch-separate-emacs-under-x
                                                         #'launch-separate-emacs-in-terminal)))))
    (save-buffers-kill-emacs)))

รหัสในการเริ่ม emacs เวอร์ชัน GUI นั้นเรียบง่าย รหัสที่จะเริ่ม emacs ใน terminal นั้นค่อนข้างยุ่งยาก มันใช้ข้อเท็จจริงที่ว่าคุณสามารถส่งผ่านสตริงsuspend-emacsที่จะถูกส่งผ่านเป็นเทอร์มินัลอินพุตไปยังกระบวนการพาเรนต์ (เชลล์) จากเอกสารประกอบ

(ระงับ emacs และ STUFFSTRING ที่เป็นตัวเลือก)

หยุด Emacs และกลับสู่กระบวนการที่เหนือกว่า คุณสามารถดำเนินการต่อในภายหลัง หาก `ไม่สามารถหยุดชั่วคราว 'ไม่ใช่ศูนย์หรือถ้าระบบไม่รองรับการควบคุมงานให้เรียกใช้ซับเพลลแทน

หาก ARG ตัวเลือกเสริม STUFFSTRING ไม่ใช่ศูนย์ตัวละครของมันจะถูกยัดให้อ่านเป็นอินพุตเทอร์มินัลโดยผู้ปกครองของ Emacs หลังจากระงับ

ดังนั้นโดยทั่วไปเราระงับ emacs ก่อนที่มันจะถูกฆ่าบอกให้ shell แม่กลับมาใช้ emacs ที่ถูกระงับชั่วคราว (ซึ่งกำลังจะออกเร็ว ๆ นี้) แล้วเปิดกระบวนการ emac โปรดทราบว่าสิ่งนี้จะไม่ทำงานบนแพลตฟอร์มที่เทอร์มินัล emacs สามารถ / ไม่หยุดชั่วคราว แต่เริ่มการทำงานของเชลล์ย่อยเช่นบน windows


สิ่งนี้ไม่ได้ผลสำหรับฉัน: เมื่อฉันเรียกใช้sh -c "emacs &"จากเชลล์มันหยุดด้วย " emacs: standard input is not a tty" (เมื่อฉันทำM-x restart-emacsฉันไม่เห็นแม้แต่ข้อความแสดงข้อผิดพลาด Emacs เพียงแค่ยกเลิก)
Constantine

ใช้งานได้สำหรับฉันภายใต้ X จะไม่ทำงานในเทอร์มินัลเพราะมันเปลี่ยนเส้นทาง stdin และ stdout ไปที่ / dev / null; การส่ง tty พาเรนต์ไปยังกระบวนการย่อยน่าจะทำได้ แต่มีเล่ห์เหลี่ยม
Beni Cherniavsky-Paskin

1
มันใช้งานได้ดีและมันทำให้ฉันกลัวเล็กน้อย ทำไม Emacs บนโลกจึงอนุญาตให้ส่งคำสั่งไปยังเชลล์ที่บรรจุอยู่?
Radon Rosborough

คุณใช้ปุ่มลัดอันไหน
slk500

32

เท่าที่ฉันรู้ว่าคุณไม่สามารถบอกให้ Emac เริ่มต้นใหม่ได้หลังจากสิ้นสุด แต่คุณสามารถตั้งรหัสทางออกเพื่อให้กระบวนการที่เริ่ม Emacs ในตอนแรกสามารถตรวจพบว่าคุณต้องการเริ่มต้นใหม่

ตัวอย่างเช่นเชลล์สคริปต์นี้เริ่มต้น Emacs ใหม่หากออกจากด้วยรหัส 123

#!/bin/sh
while emacs -nw "$@"; [ $? = 123 ]; do :; done

ถัดไปเรากำหนดkill-emacs-and-restartว่าทำให้ Emacs ยุติด้วยรหัสทางออกเท่ากับจำนวนเวทย์ที่สคริปต์รับรู้:

(defun kill-emacs-and-restart ()
  (interactive)
  (kill-emacs 123))

ตอนนี้ถ้าคุณเรียกใช้ Emacs ผ่านสคริปต์นี้คุณสามารถเริ่มต้นใหม่ด้วยM-x kill-emacs-and-restart(หรือผูกไว้กับลำดับของคีย์)


วิธีที่ดีในการแก้ไขปัญหารอบ! you cannot tell Emacs to re-start after terminatingฉันจะยอมรับเรื่องนี้ถ้าคุณสามารถบอกฉันทำไม นี่เป็นข้อ จำกัด ทางเทคนิคหรือไม่?
PythonNut

3
@PythonNut: เท่าที่ฉันรู้วิธีเดียวที่จะเริ่มต้นกระบวนการใหม่ได้โดยใช้หนึ่งในฟังก์ชั่นจากexec...ตระกูล (บนระบบ POSIX ต่อไป) ฟังก์ชั่นการควบคุมกระบวนการ Emacs Lispไม่เปิดเผยการเรียกระดับต่ำเช่นนี้ แม้ว่าฉันไม่ใช่ผู้เชี่ยวชาญ แต่หวังว่าจะมีใครบางคนที่มีความรู้มากกว่าจะพูดสอดรับ
Constantine

2

ขโมยโจ๋งครึ่มจากhttps://unix.stackexchange.com/questions/114238/is-it-possibe-to-change-parent-shells-working-directory-programmatically

สมมติว่าฉันมีไวยากรณ์ที่ถูกต้องสำหรับการฝัง "ในสตริงสิ่งนี้ควรทำ

(defun restart-emacs ()
  (call-process "sh" nil nil nil "-c" "gdb -p $(ps h -o ppid -p $$) -ex 'call execl(\"/bin/sh\", \"/bin/sh\", \"-c\", \"exec emacs\")'"))

11
โปรดอย่า นี้ทะลุทั้งหมดของการทำความสะอาดภายใน Emacs และทิ้งทุกรัฐในปัจจุบัน (เช่นบัฟเฟอร์แก้ไข) โดยไม่มีการยืนยัน
Lunaryorn

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