คุณ 'ทำซ้ำ' การเปลี่ยนแปลงหลังจาก 'ยกเลิก' กับ Emacs อย่างไร


268

บทความนี้บอกว่า "Emacs มีการทำซ้ำเพราะคุณสามารถย้อนกลับทิศทางได้ในขณะที่เลิกทำจึงเลิกทำการเลิกทำ"

สิ่งนี้หมายความว่า? ผู้ใช้จะ 'ทำซ้ำ' กับ Emac ได้อย่างไร


3
คำตอบใต้คำตอบที่ได้รับการยอมรับจะบอกคุณว่าถ้านั่นเป็นสาเหตุที่คุณกำลังดูคำตอบนี้ซึ่งตามที่เขียนไว้ฉันคาดว่าคนส่วนใหญ่จะมองหาสิ่งนั้น
Aaron Hall

ฉันแค่กด space bar แล้วก็เลิกทำหลังจากนั้นเลิกทำ space แล้วทำ undos ที่คุณทำจนกระทั่งมันถึงจุดสิ้นสุดจากนั้นก็เริ่มย้อนกลับไปอีกครั้ง ... ฉันรู้ว่ามันมีวิธีที่ซับซ้อนกว่ามาก แต่นี่เร็วและ ง่ายและนั่นคือวิธีที่ฉันหมุน
nroose

คำตอบ:


294

เวอร์ชั่นสั้น: โดยการเลิกทำการเลิกทำ หากคุณเลิกทำแล้วทำคำสั่งที่ไม่แก้ไขเช่นC-fจากนั้นการเลิกทำครั้งต่อไปจะยกเลิกการเลิกทำส่งผลให้เกิดการทำซ้ำ

รุ่นที่ยาวกว่า:

คุณสามารถนึกถึงการเลิกทำการทำงานบนกองการปฏิบัติการ หากคุณดำเนินการคำสั่งบางอย่าง (แม้แต่คำสั่งการนำทางเช่นC-f) หลังจากลำดับของการดำเนินการเลิกทำ undos ทั้งหมดจะถูกผลักไปยังกองปฏิบัติการ ดังนั้นถัดไปยกเลิกการยกเลิกคำสั่งสุดท้าย สมมติว่าคุณมีลำดับการดำเนินการที่มีลักษณะดังนี้:

  1. แทรก "foo"
  2. แทรก "บาร์"
  3. แทรก "ฉันชอบสแปม"

ตอนนี้คุณเลิกทำ มันเลิกทำการกระทำล่าสุดส่งผลให้รายการต่อไปนี้:

  1. แทรก "foo"
  2. แทรก "บาร์"

หากคุณทำสิ่งอื่นนอกเหนือจากเลิกทำ ณ จุดนี้ - พูด, C-fสแตกการดำเนินการจะเป็นดังนี้:

  1. แทรก "foo"
  2. แทรก "บาร์"
  3. แทรก "ฉันชอบสแปม"
  4. เลิกทำการแทรก "ฉันชอบสแปม"

ตอนนี้เมื่อคุณเลิกทำสิ่งแรกที่เลิกทำคือเลิกทำ ส่งผลให้สแต็กดั้งเดิมของคุณ (และสถานะเอกสาร):

  1. แทรก "foo"
  2. แทรก "บาร์"
  3. แทรก "ฉันชอบสแปม"

หากคุณใช้คำสั่งแก้ไขเพื่อแยกลำดับการเลิกทำคำสั่งนั้นจะถูกเพิ่มหลังจากเลิกทำและเป็นสิ่งแรกที่จะถูกยกเลิกในภายหลัง สมมติว่าคุณ backspaced มากกว่า "บาร์" C-fแทนการกดปุ่ม แล้วคุณจะมี

  1. แทรก "foo"
  2. แทรก "บาร์"
  3. แทรก "ฉันชอบสแปม"
  4. เลิกทำการแทรก "ฉันชอบสแปม"
  5. ลบ "บาร์"

การเพิ่ม / การเพิ่มใหม่นี้จะเกิดขึ้นกับ infinitum ของโฆษณา ใช้เวลาเล็กน้อยในการทำความคุ้นเคย แต่มันทำให้ Emacs มีกลไกการเลิกทำ / ทำซ้ำที่ยืดหยุ่นและมีประสิทธิภาพสูง


117
ในกรณีที่ฟังดูน่ารำคาญข้อได้เปรียบที่สำคัญคือคุณสามารถกลับสู่สถานะก่อนหน้าได้ตลอดเวลา ในบรรณาธิการส่วนใหญ่การยกเลิกการเปลี่ยนแปลงหลายอย่างจากนั้นการพิมพ์อักขระโดยไม่ตั้งใจจะทำให้คุณ 'ติดค้าง' โดยไม่สามารถทำซ้ำสิ่งที่คุณเลิกทำได้ Emacs ทำให้เรื่องเล็กน้อยนี้
phils

3
ฉันคิดว่าในการก่อสร้างของคุณถ้าคนต้องการที่จะทำมันบนกระดาษคุณจะต้องสองกองเพราะถ้าเป็นตัวอย่าง ณ จุดที่คุณเขียนว่า "ตอนนี้คุณเลิกทำมันเลิกทำการกระทำครั้งสุดท้ายส่งผลให้ต่อไปนี้ รายการ: "คุณ (เข้าใจได้) ไม่ได้แสดงการเลิกทำและถ้าเขาทำหลาย ๆ การเลิกทำคุณจะไม่แสดงจนกว่าจะมีบางอย่างที่ทำเพื่อแบ่งลำดับการเลิกทำคุณจะต้องเพิ่ม อีกวิธีในการแสดงว่าจะมีหนึ่งรายการและเพิ่ม undos ลงในรายการก่อนที่จะแตก แต่จะต้องทราบว่าเคอร์เซอร์อยู่ที่ไหนในรายการดังนั้นเราจึงทราบว่าการ
เลิก

25
มันฟังดูน่ารำคาญ
เฟลิเป้

13
ผมไม่ทราบว่าทำไมคำตอบนี้ได้รับการยอมรับเมื่อมันไม่ได้บอกคุณวิธี
Aaron Hall

8
น่าเศร้าที่คำตอบนี้ไม่ได้พูดอะไรเกี่ยวกับคำสั่งทำซ้ำซึ่งเป็น Cg C- /
vishnuprasanth

211

วิธียกเลิก: C-_

หากต้องการทำซ้ำหลังจากเลิกทำ: C-g C-_

พิมพ์หลาย ๆ ครั้ง C-_ เพื่อทำซ้ำสิ่งที่เลิก C-_ ทำโดยการทำซ้ำคำสั่ง emacs หลายครั้งดำเนินการคำสั่งของคุณจากนั้นพิมพ์C-xzแล้วพิมพ์หลายครั้งที่zสำคัญเพื่อทำซ้ำคำสั่ง (น่าสนใจเมื่อคุณต้องการเรียกใช้แมโครหลายครั้ง)


4
ในการทำซ้ำสิ่งต่าง ๆ ที่คุณสามารถใช้C-uเช่นC-u 8 *(แทรกแปด * ที่เครื่องหมายรูปหมวก) ดังนั้นคุณสามารถใช้C-u x C-_เพื่อเลิกทำxขั้นตอน
แพทริค

10
สิ่งนี้ไม่เกี่ยวกับคำถามเดิม แต่หลังจากเรียกใช้แมโครแป้นพิมพ์ (ด้วยC-x e) คุณสามารถกดได้eบ่อยเท่าที่คุณต้องการเพื่อเรียกใช้งานอีกครั้ง
Christian Berg

7
นอกจากนี้C-/และเป็นทางเลือกที่เลิกผูกที่สำคัญเทียบเท่ากับC-x u C-_ฉันชอบC-/เพราะมันตีง่ายกว่า
Rory O'Kane

8
คำเตือน: เมื่อคำตอบนี้บอกว่าC-g C-_จะ "ทำซ้ำหลังจากเลิกทำ" นั่นจะใช้เฉพาะในครั้งแรกที่คุณรวมกัน C-gหลังจากนั้นทำซ้ำที่สำคัญของคุณโดยไม่ยกเลิก C-g C-_ C-_ C-_ดังนั้นจะทำซ้ำสามครั้งหลังจากยกเลิกประเภท หากคุณพิมพ์C-g C-_ C-g C-_ C-g C-_คุณจะไปเป็นวงกลมยกเลิกการทำซ้ำของคุณเลิก ...
Rory O'Kane

@ RoryO'Kane ฉันไม่รู้มากเกี่ยวกับ emacs ดังนั้นโปรดแก้ไขให้ฉันในที่ที่ฉันผิด แต่เนื่องจาก Cg C-_ ไม่มีผลใด ๆ หลังจากการทำซ้ำอาจเป็นเพราะมันทำงานหลังจาก การเลิกทำ (เช่น descrption ของคุณ "ทำซ้ำหลังจากเลิกทำ" แนะนำดังนั้นจึงไม่มากนักที่จะทำซ้ำการเลิกทำหรือทำซ้ำ ฯลฯ มันไม่ได้ทำอะไรเพราะการเลิกทำไม่ได้ทำมาก่อนดังนั้น Cg C- _ Cg C-_ จะไม่วนเป็นวงกลมหลังจากอันแรกมันไม่ทำอะไรเลยอย่างแท้จริง
barlop

56
  • หากต้องการยกเลิกหนึ่งครั้ง:C-/
  • วิธีเลิกทำสองครั้ง: C-/ C-/
  • หากต้องการทำซ้ำครั้งเดียวทันทีหลังจากเลิกทำ:C-g C-/
  • หากต้องการทำซ้ำสองครั้งทันทีหลังจากเลิกทำ: C-g C-/ C-/. โปรดทราบว่าC-gจะไม่ทำซ้ำ
  • หากต้องการยกเลิกทันทีอีกครั้งหนึ่งครั้ง:C-g C-/
  • หากต้องการยกเลิกทันทีอีกครั้งให้ทำสองครั้ง: C-g C-/ C-/
  • หากต้องการทำซ้ำอีกครั้งเหมือนกัน ...

หากคุณกดปุ่มใด ๆ (ไม่ว่าจะเป็นการพิมพ์ตัวอักษรหรือเพียงแค่เลื่อนเคอร์เซอร์) ตั้งแต่คำสั่งเลิกทำล่าสุดของคุณไม่จำเป็นต้องพิมพ์C-gก่อนที่จะเลิกทำ / ทำซ้ำครั้งต่อไป C-gเป็นเพียงรหัสปลอดภัยที่จะกดปุ่มซึ่งจะไม่ทำอะไรเลยด้วยตัวเอง แต่นับเป็นคีย์ที่ไม่เลิกทำเพื่อส่งสัญญาณการสิ้นสุดของลำดับการเลิกทำของคุณ กดคำสั่งอื่นเช่นC-fจะทำงานเกินไป; เป็นเพียงว่ามันจะย้ายเคอร์เซอร์จากที่ที่คุณมีมัน

หากคุณกดปุ่มC-gหรือคำสั่งอื่นเมื่อคุณไม่ได้ตั้งใจและตอนนี้คุณกำลังยกเลิกในทิศทางที่ไม่ถูกต้องเพียงกดC-gเพื่อกลับทิศทางของคุณอีกครั้ง คุณจะต้องยกเลิกการทำซ้ำผ่านการทำซ้ำและการเลิกทำโดยไม่ตั้งใจก่อนที่คุณจะไปถึงการยกเลิกที่คุณต้องการ แต่ถ้าคุณกดปุ่มต่อC-/ไปคุณจะต้องไปถึงสถานะที่คุณต้องการในที่สุด ในความเป็นจริงทุกสถานะที่เคยบัฟเฟอร์สามารถเข้าถึงได้ถ้าคุณกดC-gหนึ่งครั้งแล้วกดC-/ครั้งมากพอ

ทางลัดทางเลือกสำหรับundoอื่น ๆ กว่าC-/มีC-_, และC-x uM-x undo

ดูเลิกทำในคู่มือการใช้งาน Emacs สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับระบบการเลิกทำการของ Emacs


38

สำหรับผู้ที่ต้องการให้มีการยกเลิกการทำงานร่วมกันมากขึ้น / undo-tree.elทำซ้ำบางคนได้เขียน มันให้รูปลักษณ์และความรู้สึกของการเลิกทำที่ไม่ใช่ Emacs แต่ให้การเข้าถึง 'ต้นไม้' ทั้งหมดของประวัติศาสตร์การเลิกทำ

ฉันชอบระบบเลิกทำของ Emacs แต่พบว่าแพ็คเกจนี้ใช้งานง่ายมาก

นี่คือความเห็นจากไฟล์เอง:

Emacs มีระบบเลิกทำการอันทรงพลัง ซึ่งแตกต่างจากระบบการยกเลิก / ทำซ้ำมาตรฐานซอฟต์แวร์ส่วนใหญ่จะช่วยให้คุณสามารถกู้คืนใด ๆของรัฐที่ผ่านมาของบัฟเฟอร์ (ในขณะที่ระบบการยกเลิก / ทำซ้ำมาตรฐานสามารถสูญเสียรัฐที่ผ่านมาโดยเร็วที่สุดเท่าที่จะทำซ้ำ) อย่างไรก็ตามพลังนี้มาในราคา: หลายคนพบว่าระบบเลิกทำของ Emacs เกิดความสับสนและใช้งานยากวางไข่จำนวนแพ็คเกจที่แทนที่ด้วยระบบยกเลิก / ทำซ้ำที่ใช้งานง่าย แต่มีประสิทธิภาพมากกว่า

ทั้งการสูญเสียข้อมูลที่มีมาตรฐานการเลิกทำ / ทำซ้ำและความสับสนของการเลิกทำของ Emacs เกิดจากการพยายามที่จะรักษาประวัติศาสตร์การเลิกทำตามลำดับการเปลี่ยนแปลงเชิงเส้น มันไม่ใช่. `เลิกทำต้นไม้โหมด 'จัดทำโดยแพคเกจนี้แทนที่ระบบเลิกทำของ Emacs ด้วยระบบที่ปฏิบัติต่อประวัติศาสตร์เลิกทำในสิ่งที่มันเป็น: ต้นไม้กิ่งก้านของการเปลี่ยนแปลง แนวคิดเรียบง่ายนี้ช่วยให้สามารถใช้งานพฤติกรรมที่เป็นธรรมชาติของระบบเลิกทำ / ทำซ้ำมาตรฐานได้มากขึ้นรวมกับพลังของการไม่เคยสูญเสียประวัติใด ๆ โบนัสด้านเพิ่มคือการยกเลิกการเก็บประวัติในบางกรณีสามารถเก็บไว้ได้อย่างมีประสิทธิภาพมากขึ้นทำให้สามารถสะสมการเปลี่ยนแปลงได้มากขึ้นก่อนที่ Emacs จะเริ่มทิ้งประวัติ


3
Fantastic! ใครบอกว่า emacs เลิกทำเป็นสิ่งที่กินลึก :-)
Peter.O

! ที่น่าตื่นตาตื่นใจ แนวคิดด้านเสียงและผู้ใช้เป็นธรรมชาติ สิ่งนี้ควรอยู่ในแพ็คเกจเริ่มต้น หนึ่งความคิดเห็น: ฉันหวังว่าข้อความแจ้งเตือนบางอย่างจะปรากฏขึ้นเมื่อทำซ้ำจากจุดสาขาไม่เพียง แต่เมื่อย้อนกลับไปที่มัน ตัวอย่างเช่นเมื่อผู้ใช้เรียกใช้การทำซ้ำ: 'การทำซ้ำจากจุดสาขา' หรือ 'การทำซ้ำสาขาที่ใช้เป็นค่าเริ่มต้น' - เพียงเพื่อเตือนผู้ใช้ว่ามีสาขามากกว่าหนึ่งสาขา
Basel Shishani

1
อีกวิธีหนึ่งในการแก้ไขปัญหานี้ซึ่งง่ายกว่าในการนำไปใช้และไม่ต้องใช้ visualizer คือการรักษาเฉพาะจุดสาขาล่าสุดเท่านั้นและให้คำสั่ง 3 คำสั่ง: undo, redo, switch-branch การเลิกทำ / ทำซ้ำจะแจ้งเตือนเมื่อมีการกดสาขาและสวิตช์สาขาจะสลับหากที่สาขาอื่นเพียงแค่ออกข้อความ 'ไม่ได้อยู่ที่สาขา' หากการแตกแขนงเกิดขึ้นได้ทุกเวลาจุดกิ่งก่อนหน้านี้จะหายไป สิ่งนี้จะแก้ไขปัญหาการสูญเสียของรัฐได้ดีพอสมควรและมีความซับซ้อนน้อยที่สุด
Basel Shishani

1
ระวังสิ่งนี้มีข้อผิดพลาดอันยาวนานในการทำซ้ำซึ่งสามารถสุ่มล้มเหลว: github.com/syl20bnr/spacemacs/issues/9903 - เป็นที่รู้จักกันตั้งแต่ปี 2014
ideasman42

@ ideasman42 เห็นได้ชัดว่านี่คือ "ไม่ใช่ข้อบกพร่อง": dr-qubit.org/Lost_undo-tree_history.html
Dalker

19

ระวังการเล่นโวหารต้นไม้สำหรับทำซ้ำ !

"ชุดเลขหมาย" ยอดนิยมจำนวนมาก (โหมโรง, เพอร์เซลล์, สเปซแม็ค) มาพร้อมกับการเลิกทำต้นไม้ ส่วนใหญ่ (ทั้งหมด?) แม้เปิดใช้งานโดยอัตโนมัติ ดังที่กล่าวไว้การเลิกทำต้นไม้เป็นวิธีที่สะดวกในการมองเห็นและสำรวจต้นไม้การเลิกทำ / ทำซ้ำ โหมโรงแม้จะให้มันคีย์คอร์ด ( uu) C-x uและยัง

ปัญหาคือ: ยกเลิกต้นไม้ดูเหมือนว่าจะทำลายเริ่มต้น Emacs' และเป็นที่รู้จักผูกพันสำหรับการทำซ้ำC-g C-/ :

คุณสามารถใช้ปุ่มสมมาตรเหล่านี้แทนการเลิกทำ / ทำซ้ำ :

C-/     undo
C-S-/   redo

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


นี้. ฉันกำลังใช้ Spacemacs และไม่สามารถเข้าใจได้ว่าทำไมมันถึงไม่เหมาะกับฉัน ขอบคุณ!
mghaoui

11

ฉันพบว่าredo.elมีประโยชน์มากสำหรับการทำ "ปกติ" เลิกทำ / ทำซ้ำและฉันมักจะผูกไว้กับ CSz และเลิกทำกับ Cz เช่นนี้

(when (require 'redo nil 'noerror)
    (global-set-key (kbd "C-S-z") 'redo))

(global-set-key (kbd "C-z") 'undo)

.emacsเพียงดาวน์โหลดไฟล์ใส่ไว้ในกระเพื่อมเส้นทางของคุณและวางข้างต้นของคุณ


ความคิดเห็นในส่วนหัวของ redo.el บอกว่ามันถูกสร้างขึ้นมาสำหรับ XEmacs มีปัญหาในการใช้งานใน GNU Emacs และ Emacsen อื่น ๆ ที่เกี่ยวข้องหรือไม่?
A. เลวี

ฉันยังไม่ได้มีปัญหาใด ๆ และฉันใช้มันมาอย่างน้อย 6 เดือน :)
monotux

4
จากemacswiki.org/emacs/RedoMode : อย่างไรก็ตาม redo.el ล้าสมัยและมักจะทำลายเนื้อหาของ "บัฟเฟอร์เนื่องจากพฤติกรรมของ 'ดั้งเดิม - เลิกทำ' นั้นแตกต่างจากเก่าตั้งแต่ Emacs 22 RedoPlus เป็น ส้อมของ redo.el และทำงานได้อย่างถูกต้องใน Emacs เวอร์ชั่นใหม่คุณสามารถรับ RedoPlus ได้ที่นี่: emacswiki.org/emacs/redo+.el
rofrol

2

Emacs 28 เพิ่มคำสั่งทำซ้ำ (เรียกว่าundo-redo)

หากคุณต้องการเลิกทำ / ทำซ้ำทั่วไปมากขึ้นสามารถใช้คำสั่งต่อไปนี้ได้

(global-set-key (kbd "C-z") 'undo-only)
(global-set-key (kbd "C-S-z") 'undo-redo)

1

หากคุณต้องการที่จะทำซ้ำการดำเนินการล่าสุดทำต่อไปนี้

  1. ESC
  2. เลิกทำอีกอัน ( C + /)

0

ตามค่าเริ่มต้นการทำซ้ำใน Emacs ต้องกด Cg แล้วจึงเลิกทำ

อย่างไรก็ตามอาจเป็นไปได้ที่จะใช้ Emacs ในตัวเลิกทำเพื่อนำคำสั่งทำซ้ำไปใช้

แพ็กเกจการเลิกทำใช้ฟังก์ชันการเลิกทำของ Emac ในตัวเพื่อแสดงทั้งการเลิกทำและทำซ้ำ

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