เปลือกหมายถึงอะไรในโหมด“ vi” หรือโหมด“ emacs”?


32

คำถามนี้ดังต่อไปนี้โดยตรงจากคำตอบ ในกรณีนี้ฉันไม่สามารถเข้าใจส่วนที่ระบุว่า:

ในเรื่องนั้นพฤติกรรมของมันใกล้เคียงกับ emacs 'มากกว่าด้วยโหมด bash (readline) / ksh / zsh emacs แต่แยกออกจากตัวแก้ไขเส้นฝังไดรเวอร์ของเทอร์มินัล (ในโหมด canonical) ซึ่งCtrl-Wจะลบคำก่อนหน้า (werase และใน vi )

ที่นี่เรากำลังพูดถึงเชลล์และไม่ใช่บรรณาธิการซึ่งเป็นสองโปรแกรมที่แตกต่างกัน การบอกว่าเชลล์อยู่ในโหมดตัวแก้ไขบางอย่างหมายความว่าอย่างไร

PS: คุณสามารถยึดคำตอบของคุณบนฐานที่ฉันเข้าใจว่าเชลล์คืออะไรและใช้ vim สำหรับการแก้ไขพื้นฐานได้อย่างไร


นี่ไม่ได้เกี่ยวกับฟังก์ชั่นของคอร์เชลล์ แต่เป็นเรื่องเกี่ยวกับการแก้ไขบรรทัด (สิ่งที่คุณทำเมื่อคุณพิมพ์ผิดและกลับไปแก้ไขด้วยตัวเอง)
n คำสรรพนาม 'm

คำตอบ:


27

ในโหมด "vi" คุณสามารถแก้ไข / นำทางบนเชลล์พรอมต์ปัจจุบันเช่นบรรทัดในเครื่องมือแก้ไข vi คุณสามารถดูได้เหมือนไฟล์ข้อความบรรทัดเดียว ในโหมด "emacs" แบบอะนาล็อกคุณสามารถแก้ไข / นำทางบรรทัดคำสั่งปัจจุบันโดยใช้ทางลัด (บางส่วน) ของ Emacs

ตัวอย่าง

ตัวอย่างเช่นในโหมด vi คุณสามารถทำสิ่งที่ชอบ (ในทุบตี):

$ set -o vi
$ ls hello world
<ESC>
bbdw # results in
$ ls world

ในโหมด emacs คุณสามารถกดCtrl+ Aเพื่อข้ามไปที่จุดเริ่มต้นของบรรทัด (vi: Ctrl+ [, 0หรือESC, 0) คุณสามารถเปิดโหมด emacs ผ่านset -o emacs(ใน bash, ksh, zsh ฯลฯ )

Readline

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

ตัวอย่างเช่นการกำหนดค่า readline ของฉันดูเหมือนว่า:

$ cat ~/.inputrc 
set editing-mode vi
set blink-matching-paren on

ตัวอย่างเช่นzsh / kshไม่ได้ใช้ readline เท่าที่ฉันรู้ แต่ยังรองรับโหมด vi / emacs ที่คล้ายกับ bash / readline หนึ่งมาก

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

โหมดมาตรฐาน

ก่อนที่โหมด vi / emacs ของเชลล์บรรทัดคำสั่งแบบโต้ตอบ 'ถูกประดิษฐ์' เชลล์ของคุณจะใช้เพียงโหมด canonicalของเทอร์มินัลของคุณซึ่งมีชุดคำสั่งการแก้ไขที่ จำกัด เท่านั้น (เช่นCtrl+ Wเพื่อลบคำสุดท้าย


สมมติว่าฉันไม่รู้ว่าฉันใช้โหมดป้อนข้อมูลใดอยู่ ฉันสามารถตรวจสอบโดยป้อนข้อความและกด [Ctrl] + [A] ได้หรือไม่ ถ้าเคอร์เซอร์ย้ายไปที่การเริ่มต้น emacs อื่นมัน vi?
limovala

2
@limovala ควรเป็นการประมาณที่ดี ขึ้นอยู่กับเชลล์ของคุณแน่นอน - ถ้า CTL + A ไม่ทำงานอีกความเป็นไปได้คือเชลล์ของคุณไม่มีโหมดการแก้ไขใด ๆ บางทีเชลล์บางตัวยังใช้โหมดการแก้ไขอื่น ๆ แต่ในทางปฏิบัติวิธีการของคุณควรจะดีพอ คุณสามารถทดสอบด้วยคำสั่ง vi หลังจากนั้นเพื่อความมั่นใจมากขึ้น set -o | grep 'emacs\|vi'ในทุบตีคุณยังสามารถใช้สิ่งที่ต้องการ ใน zsh (ที่ฉันมีโหมด vi) สิ่งนี้ไม่ทำงาน
maxschlepzig

ผูก -P จะให้การบ่งชี้ที่ดีว่าโหมดใดอยู่ใน
Paul

23

คุณจะสังเกตเห็นว่าเมื่อคุณรันcatที่ shell prompt บนเทอร์มินัลcatควรจะเขียนไปยัง stdout สิ่งที่มันอ่านจาก stdin และกดaคุณจะเห็นaเสียงสะท้อนกลับโดยไดรเวอร์เทอร์มินัล แต่catไม่ได้เขียนa(คุณเห็น มีเพียงอันเดียวอันaที่สะท้อนจากไดรเวอร์เทอร์มินัล)

อย่างไรก็ตามหากคุณพิมพ์ a Backspace b Enterคุณจะไม่เห็นcatผลลัพธ์a\010b\015แต่b\012( bและขึ้นบรรทัดใหม่)

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

stty -icanon; cat

จากนั้นคุณจะเห็นทั้งecho(ซึ่งคุณสามารถปิดการใช้งานด้วยstty -echo) และcatเอาท์พุทในเวลาเดียวกัน

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

ความสามารถในการแก้ไขของตัวแก้ไขนั้นมี จำกัด มาก ในการใช้งานส่วนใหญ่มีเพียงปุ่มแก้ไข 4 ปุ่มเท่านั้น (จริง ๆ ตัวอักษร) สามารถกำหนดค่าได้ด้วยstty:

  • ลบ ( ^Hหรือ^?โดยปกติ): ลบอักขระก่อนหน้า
  • ฆ่า ( ^Uปกติ): ว่างเปล่า (ฆ่า) บรรทัดที่ป้อนจนถึง
  • werase ( ^W): ลบคำก่อนหน้า
  • lnext ( ^V): ป้อนอักขระถัดไปตามตัวอักษร (ยกเลิกความหมายพิเศษของทั้งหมดข้างต้น)

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

อย่างไรก็ตามนั่นไม่เคยเกิดขึ้นจริงอาจเป็นส่วนหนึ่งของสาเหตุที่ทำให้เกิดความวุ่นวายกับเทอร์มินัลที่แตกต่างกันซึ่งไม่ได้ส่งตัวอักษรเดียวกันกับการกดปุ่มบางปุ่มซึ่งทำให้เห็นได้ชัดว่า

ดังนั้นเชลล์บางตัวก็เริ่มดรอปโหมดcanonicalของเทอร์มินัลไดรเวอร์และใช้ตัวแก้ไขบรรทัดของตัวเอง ในเวลานั้นemacsและviเป็นบรรณาธิการข้อความภาพที่เป็นที่นิยมที่สุดที่มีการเชื่อมโยงคีย์และโหมดการทำงานที่แตกต่างอย่างสิ้นเชิง ในviคุณมีหนึ่งโหมดสำหรับการป้อนข้อความและอีกโหมดหนึ่งสำหรับการแก้ไข ในemacsคุณจะเข้าสู่โหมดข้อความเสมอแต่การแก้ไขทำได้โดยการกดคีย์ผสม (เช่น^bเลื่อนตัวอักษรไปด้านหลัง)

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

ตามhttps://www.usenix.org/legacy/publications/library/proceedings/vhll/full_papers/korn.ksh.a :

คุณสมบัติการแก้ไขแบบอินไลน์ยอดนิยม (โหมด vi และ emacs) ของ ksh ถูกสร้างขึ้นโดยนักพัฒนาซอฟต์แวร์ที่ Bell Laboratories; โหมดแก้ไขบรรทัด vi โดย Pat Sullivan และโหมดแก้ไขบรรทัด emacs โดย Mike Veach แต่ละคนมีการปรับเปลี่ยนเชลล์เป้าหมายเพื่อเพิ่มคุณสมบัติเหล่านี้และทั้งสองอยู่ในองค์กรที่ต้องการใช้ ksh เฉพาะเมื่อ ksh มีเครื่องมือแก้ไขอินไลน์ตามลำดับ เดิมแนวคิดของการเพิ่มการแก้ไขบรรทัดคำสั่งไปยัง ksh ถูกปฏิเสธด้วยความหวังว่าการแก้ไขบรรทัดจะย้ายเข้าสู่ไดรเวอร์เทอร์มินัล อย่างไรก็ตามเมื่อเห็นได้ชัดว่าสิ่งนี้ไม่น่าจะเกิดขึ้นในไม่ช้าทั้งสองโหมดแก้ไขบรรทัดจะรวมเข้ากับ ksh และทำให้เป็นทางเลือกเพื่อให้สามารถปิดการใช้งานบนระบบที่ให้การแก้ไขเป็นส่วนหนึ่งของเทอร์มินัลอินเตอร์เฟส

ดังนั้นพวกเขาจึงติดตั้งทั้งสองและอินเทอร์เฟซสำหรับผู้ใช้เพื่อเลือกระหว่างสอง kshอาจเป็นครั้งแรกในช่วงต้นยุค 80 (การใช้รหัสซ้ำที่เขียนแยกต่างหากเพื่อเพิ่มโหมด vi และโหมด emacs ไปยังบอร์นเชลล์ดังที่เห็นด้านบน) ตามด้วยtcsh( tcshตอนแรกมีเพียงการemacsเชื่อมโยงคีย์เท่านั้นviโหมดเพิ่มในภายหลัง) bashและzshในช่วงต้นยุค 90

คุณสลับระหว่างสองโหมดbash, zshหรือkshด้วยset -o viหรือset -o emacsและด้วยbindkey -eหรือbindkey -vในหรือtcshzsh

POSIX ระบุviโหมดจริงและไม่ใช่emacsโหมดสำหรับsh(เรื่องราวมีRichard Stallman คัดค้าน POSIX เพื่อระบุemacsโหมดสำหรับsh )

โหมดเริ่มต้นสำหรับbashโดเมนสาธารณะสายพันธุ์ของksh(pdksh, mksh, oksh) tcshและzshเป็นโหมด emacs (แม้ว่าจะมีzshก็viถ้า$EDITORมีvi) ในขณะที่ AT & T kshก็เป็นใบ้โหมดเว้นแต่$EDITORหรือ$VISUALกล่าวถึงหรือviemacs

kshภายหลังได้เพิ่มgmacsโหมดเพื่อรองรับผู้ใช้ Gosling emacsที่จัดการCtrl+Tแตกต่างกัน

ตอนนี้จัดการของ^Wในemacsหรือtcshemacs โหมดอาจถือกำเนิดweraseตัวละครในบรรณาธิการสายขั้วดังนั้นเราจึงไม่สามารถจริงๆตำหนิพวกเขาสำหรับการที่และคำสั่งของฉันเกี่ยวกับ"แยกย้ายกัน ..."อาจจะถูกมองว่าเป็นความเข้าใจผิด มันเป็นแค่ที่ฉันคิดว่ามันเกิดการระคายเคืองเมื่อสิ่งที่ชอบemacs, tcshหรือมีพฤติกรรมที่แตกต่างจากทุกอย่างอื่นเมื่อคุณพิมพ์info คุณสามารถจินตนาการผมพบว่ามันเกิดการระคายเคืองมากขึ้นเมื่อใช้งานบางอย่างเริ่มที่จะปิดหน้าต่างของพวกเขาเมื่อคุณพิมพ์Ctrl-W Ctrl-W


1
pdkshยังแยกวิเคราะห์$EDITORสำหรับviและสวิทช์โหมดเมื่อเริ่มต้น; ฉันลบสิ่งนั้นสำหรับmksh(โดยเฉพาะอย่างยิ่งเมื่อฉันรักษาโหมด Emacs เอาไว้เท่านั้น)
mirabilos

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

ขอบคุณสำหรับบริบททางประวัติศาสตร์ที่ยอดเยี่ยม มันน่าเสียดายที่ฟีเจอร์การแก้ไขแบบอินไลน์ที่ซับซ้อนมากขึ้นไม่ได้ถูกเพิ่มลงในไดรเวอร์เทอร์มินัลในเวลานั้น ไม่จำเป็นต้องมีโปรแกรมที่จะรวมไลบรารี่เช่น Readline ฉันสงสัยด้วยว่าทำไม Emacs-mode ไม่ได้ระบุไว้โดย POSIX ดังนั้นลิงก์ไปยัง Rationale จึงน่าสนใจ (ฉันยังแบ่งปันความคับข้องใจของคุณกับ^Wหน้าต่างปิด)
Anthony G - ความยุติธรรมสำหรับโมนิก้า

1
@AththonyGeoghegan เรายังต้องการสิ่งต่าง ๆ เช่น zle / readline เพราะสิ่งต่าง ๆ เช่นชื่อไฟล์ / คำสั่งเสร็จสิ้นไม่สามารถทำได้ในไดรเวอร์เทอร์มินัล
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.