ในโหมด bash vi แผนที่ jk เพื่อออกจากโหมดแทรก


12

ฉันใช้อูบุนตู 16.04 ติดตั้งใหม่กับเปลือกทุบตี มีสองสิ่งที่ฉันต้องการทำ:

  1. ตั้งค่าโหมด vi เพื่อให้ฉันสามารถมีการเคลื่อนไหวเหมือนเป็นกลุ่มจากเทอร์มินัล
  2. ออกจากโหมดแทรกโดยการพิมพ์ jk

ฉันอ่านในโพสต์อื่นว่าสิ่งนี้สามารถทำได้ด้วยzshฉันจะทำอย่างไรกับbash?

TL; DR

ใส่bind '"jk":vi-movement-mode'ลงใน.bashrcไฟล์ของคุณหลังจากset -o vi:)

server@thinkpad:~$ tail -n 2 .bashrc
set -o vi
bind '"jk":vi-movement-mode'

โปรดดูคำตอบของ @ grochmal สำหรับคำอธิบายโดยละเอียดเพิ่มเติม


1
คุณหมายถึงอะไรโดยแมปเพื่อjk? นั่นคือกุญแจพิเศษบางอย่างบนแป้นพิมพ์ของคุณ?
Stephen Harris

โปรดดูการแก้ไข
mbigras

สำหรับครั้งแรกของคุณ.bashrcโดยทั่วไปจะถูกเรียกบนทุก ๆ เชลล์ (เช่นถ้าคุณใช้เปลือกนอกvi) แต่.bash_profileจะเรียกเฉพาะในเปลือกเข้าสู่ระบบเท่านั้น ดังนั้นเป็นสถานที่ที่เหมาะสมสำหรับ.bashrc set -o viฉันไม่มีคำตอบสำหรับคำถามที่ 2 ที่แก้ไขของคุณ :-(
Stephen Harris

คุณเริ่มเปลือก bash อย่างไร นี่คือคำอธิบายที่ดีเกี่ยวกับความแตกต่างระหว่าง. bashrc และ. bash_profile
the_velour_fog

คำตอบ:


11

TL; DR

ทุบตีมีการทำงานคล้ายกับzsh's bindkeyผ่านbindแต่มันไม่ได้มีหลายรูปแบบเช่นvi zshหลังจากที่set -o viคุณสามารถทำได้:

bind '"jk":vi-movement-mode'

ซึ่งเทียบเท่าของzsh'sbindkey -M <all vi modes> jk vi-movement-mode

vi-movement-modeฟังก์ชั่นมาจากinputrc(ดู/etc/inputrcรายชื่อของพวกเขา)

ข้อความเต็ม

สตีเฟ่นแฮร์ริสชี้ให้เห็นในความคิดเห็นของเขา:

  • .bashrcถูกเรียกโดยbashเสมอ (และไม่โดดเด่นด้วยกระสุนอื่น)

  • .bash_profile ถูกเรียกบนเชลล์ล็อกอินเท่านั้น (และอีกครั้ง, ทุบตีเท่านั้น)

หลาย distros มาพร้อมกับ.bash_profileโครงกระดูกที่มีลักษณะดังนี้:

# ~/.bash_profile
[[ -f ~/.bashrc ]] && . ~/.bashrc

ซึ่งเป็นเนื้อหาที่ดี.bash_profileเพราะคุณสามารถลืมมันได้

ตอนนี้การแมปjkไปEscในเซสชั่นเปลือกนั่นเป็นไปไม่ได้จริงๆ เมื่อคุณทำ:

inoremap jk <esc>

ใน Vim หลังจากคุณพิมพ์jVim รู้ว่าต้องรอนิดหน่อยเพื่อดูว่าคุณพิมพ์kถัดไปหรือไม่และควรเรียกใช้การจับคู่ (หรือคุณพิมพ์คีย์อื่นและไม่ควรเรียกใช้การแมป) เป็นภาคผนวกนี้ถูกควบคุมโดย:set timeoutlen=<miliseconds>ในกลุ่ม (ดู:h timeoutlen)

เชลล์หลายตัวหรือ X11 ไม่มีการควบคุมการหมดเวลาและไม่อนุญาตให้ทำการแมปอักขระหลายตัว อนุญาตการทำแผนที่ของคีย์เดียวเท่านั้น (แต่ดูหมายเหตุสนับสนุนด้านล่าง)

set -o vi

ไม่ได้อ่าน.vimrcมันเลียนแบบการผสมคีย์บางอย่างvi(ไม่เท่ากันvim) ที่สามารถใช้ในเชลล์ได้ เช่นเดียวกับที่ได้กล่าวเกี่ยวกับมันไม่ได้มาด้วยอำนาจเต็มของ-o emacsemacs


สนับสนุน zsh

zshจริง ๆ แล้วสนับสนุนการหมดเวลาของแผนที่ และคุณสามารถใช้แผนที่ต่อไปนี้jkเพื่อ<esc>:

bindkey -v  # instead of set -o vi
bindkey -e jk \\e

(นั่นจะต้องไป~/.zshrcไม่ได้~/.bashrc)

ถึงกระนั้นฉันแนะนำต่อนี้ ฉันใช้vimและzshส่วนใหญ่เวลา ฉันมีinoremap jk <esc>ในตัวของฉันvimrcและฉันได้ลองใช้bindkeyชุดค่าผสมด้านบน zshรอนานเกินไปที่จะพิมพ์jเมื่อใช้งานและนั่นทำให้ฉันรำคาญมาก


สนับสนุนทุบตี

bashreadline bindสนับสนุน ฉันเชื่อว่าbashสามารถรวบรวมได้โดยไม่ต้องreadilneมีบางระบบที่หายากที่มีการทุบตีที่ไม่สนับสนุนbind(ระวังตัว) ต้องการแมปjkไป<esc>ในbashที่คุณต้องทำ:

set -o vi
bind '"jk":"\e"'

(ใช่ว่าเป็นข้อความสองระดับจำเป็นต้องมี)

ทำให้การพิมพ์jน่ารำคาญอีกครั้ง แต่อย่างใดที่น่ารำคาญน้อยกว่าzshวิธีการแก้ปัญหาในเครื่องของฉัน


วิธีแก้ปัญหา (สำหรับเชลล์ที่ไม่ใช่ bash และ non-zsh)

เหตุผลในการแมปEscกุญแจใหม่คือปุ่มนั้นอยู่ไกลจากแป้นพิมพ์มากและการพิมพ์ต้องใช้เวลา เคล็ดลับที่สามารถยืมได้จากemacsพวกนั้นคือทำการแมปใหม่CapsLockเพราะมันเป็นกุญแจที่ไร้ประโยชน์อยู่ดี emacsพวกทำการแมปไปCtrlแต่เราจะทำการแมปEscใหม่

ลองใช้xev -event keyboardเพื่อตรวจสอบ keycode ของCapsLock:

KeyPress event, serial 25, synthetic NO, window 0x1c00001,
    root 0x496, subw 0x0, time 8609026, (764,557), root:(765,576),
    state 0x0, keycode 66 (keysym 0xffe5, Caps_Lock), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

และเพื่อตรวจสอบการทำงานของEsc:

KeyPress event, serial 25, synthetic NO, window 0x1c00001,
    root 0x496, subw 0x0, time 9488531, (571,525), root:(572,544),
    state 0x0, keycode 9 (keysym 0xff1b, Escape), same_screen YES,
    XLookupString gives 1 bytes: (1b) "
    XmbLookupString gives 1 bytes: (1b) "
    XFilterEvent returns: False

ดีมากCapsLockคือรหัสกุญแจ 66 และEscฟังก์ชั่นของมันถูกเรียกว่า "Escape" ตอนนี้เราสามารถทำได้:

# diable caps lock
xmodmap -e "remove lock = Caps_Lock"
# make an Esc key from the keycode 66
xmodmap -e "keycode 66 = Escape"

ต้องทำตามลำดับข้างต้นนี้ ตอนนี้ทุกครั้งที่คุณกดปุ่มCapsLockมันจะทำงานเหมือนเป็นEscกุญแจ


ส่วนที่ยากคือที่ตั้งนี้ ไฟล์ที่~/.Xmodmapมีเนื้อหา:

remove lock = Caps_Lock
keycode 66 = Escape

ควรได้รับการเคารพจาก distros ส่วนใหญ่ (จริง ๆ แล้วเป็นผู้จัดการการแสดง แต่ฉันกำลังพูดถึง distros เพื่อความเรียบง่าย) แต่ฉันเห็นคนที่ไม่เคารพ~/X*ไฟล์หลายไฟล์ สำหรับสิ่งที่รบกวนคุณอาจลองทำสิ่งต่อไปนี้:

if [ "x" != "x$DISPLAY" ]; then
    xmodmap -e "remove lock = Caps_Lock"
    xmodmap -e "keycode 66 = Escape"
fi

.bashrcในของคุณ

(ในทางทฤษฎีที่น่าจะอยู่ในตำแหน่งที่ดีกว่า~/.xinitrcแต่ถ้าผู้จัดการการแสดงผลไม่เคารพ.Xmodmapมันจะไม่เคารพอย่างแน่นอน~/.xnintrc)

หมายเหตุพิเศษ: นี้เท่านั้น remaps CapsLockไปEscในเซสชั่ X11 จึงแผนที่จะทำงานเฉพาะในการเลียนแบบขั้ว ที่จริงแล้วttyจะไม่เห็นแผนที่

การอ้างอิงและการอ่านพิเศษ:


ขอบคุณสำหรับคำอธิบายรายละเอียด คุณยินดีที่จะแสดงกระบวนการเดียวกันยกเว้นการทำแผนที่jkแทนCapsLockหรือไม่? ฉันได้ตั้งไว้ในเครื่อง osx ของฉัน; แต่ผมยังไม่ได้เวลาที่เหลือของวันหยุดสุดสัปดาห์และฉันไม่สามารถจำได้ว่าฉันไม่ได้ :)
mbigras

@mbigras - คุณแน่ใจหรือว่าคุณทำมันด้วยการทุบตี? Bash ไม่มีแผนที่ที่น่าสงสัย ฉันรู้วิธีการทำในzsh: bindkey -v; bindkey -s jk \\e. แต่นั่นคือสิ่งที่จะกลับมาและกัดคุณกลับมาเมื่อคุณต้องการjkเพราะจับเวลาไม่ได้กำหนดและคุณไม่มีใน<leader> zsh
grochmal

ฉันทำอย่างนั้นแน่นอนzshและไม่bashเป็นไปไม่ได้ในการทุบตี?
mbigras

@mbigras - เดี๋ยวก่อนฉันผิด! อ่านหนังสือman bashผมพบว่าbindการทำงานที่สวยคล้ายกับ'szsh bindkeyฉันจะอัปเดตคำตอบ ไปแล้วฉันใช้zshมากเกินไป
grochmal

2
@Jason - เฮ้นี่คือ Vi SE ในที่นี้ทุกคนเขียนคำ CAPS ทั้งหมดด้วย: "type word" <Esc> viwU :) ไม่จำเป็นต้องเสร็จสมบูรณ์
grochmal

2

ขอบคุณสำหรับคำตอบก่อนหน้านี้ฉันใช้สิ่งนี้ใน~ / .zshrcสำหรับทางลัด vi-like ใน terminal ของฉัน ฉันหวังว่ามันจะช่วยใครซักคน

bindkey -v
bindkey 'jk' vi-cmd-mode

ฉันมาที่นี่เพื่อค้นหาคำตอบที่ใช้สำหรับผูกปุ่ม '^ G' เพื่อเข้าสู่ "โหมดปกติ" ใน zsh ที่เปิดใช้งาน vi และนี่เป็นคำเดียวที่ใช้ได้
Dalker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.