बैश vi मोड में, इन्सर्ट मोड से बाहर निकलने के लिए मैप jk


12

मैं बैश शेल के साथ ubuntu 16.04 की एक ताजा स्थापना का उपयोग कर रहा हूं। दो चीजें हैं जो मैं करना चाहता हूं:

  1. Vi मोड सेट करें ताकि मैं टर्मिनल से विम-जैसे मूवमेंट कर सकूं
  2. टंकण मोड से बाहर निकलें jk

मैंने एक और पोस्ट में पढ़ा कि यह कैसे किया जा सकता है zsh, मैं इसे कैसे कर सकता हूं bash?

tl; डॉ

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? क्या आपके कीबोर्ड पर कुछ विशेष कुंजी है?
स्टीफन हैरिस

कृपया देखें
mbigras

आपके पहले के लिए, .bashrcआमतौर पर हर शेल पर कॉल किया जाता है (उदाहरण के लिए यदि आप शेल से बाहर हैं vi) लेकिन .bash_profileकेवल लॉगिन शेल पर कहा जाता है। तो .bashrcके लिए सही जगह है set -o vi। आपके संशोधित 2 वें प्रश्न का जवाब मेरे पास नहीं है :-(
स्टीफन हैरिस

आप अपना बैश शेल कैसे शुरू कर रहे हैं? यहाँ .bashrc और
.bash_profile

जवाबों:


11

टी एल; डॉ

बैश लिए एक समान कार्यक्षमता है zsh'एस bindkeyके माध्यम से bind, लेकिन यह कई नहीं है viकी तरह मोड zshset -o viआप कर सकते हैं के बाद :

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

जो के बराबर है zshकीbindkey -M <all vi modes> jk vi-movement-mode

vi-movement-modeकार्यों से आता है inputrc(देखें /etc/inputrcउनमें से एक सूची के लिए)।

पूर्ण पाठ

जैसा कि स्टीफन हैरिस अपनी टिप्पणी में बताते हैं:

  • .bashrcbashहमेशा कहा जाता है (और विशेष रूप से अन्य गोले द्वारा नहीं)।

  • .bash_profile केवल लॉगिन गोले पर कॉल किया जाता है (और फिर से, केवल बैश)।

कई डिस्ट्रोस एक .bash_profileकंकाल के साथ आते हैं जो निम्नानुसार दिखता है:

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

जो एक अच्छी सामग्री है .bash_profileक्योंकि आप इसे भूल सकते हैं कि यह मौजूद है।

अब, शेल सत्र में मैप jkकरना Esc, यह वास्तव में संभव नहीं है। जब तुम करोगे:

inoremap jk <esc>

आपके टाइप करने के बाद jविम में, विम को पता है कि यह देखने के लिए थोड़ा इंतजार करने की जरूरत है कि क्या आप kअगले टाइप करते हैं और इसे मैपिंग को इनवॉइस करना चाहिए (या कि आप दूसरी कुंजी टाइप करें और मैपिंग ट्रिगर नहीं होनी चाहिए)। परिशिष्ट के रूप में यह :set timeoutlen=<miliseconds>विम (देखें :h timeoutlen) द्वारा नियंत्रित किया जाता है ।

कई शेल या X11 का इस तरह का कोई समय पर नियंत्रण नहीं है और यह कई कैरेक्टर मैपिंग की अनुमति नहीं देता है। केवल एक ही कुंजी के मानचित्रण की अनुमति है (लेकिन नीचे समर्थन नोट देखें।)।

set -o vi

पढ़ता नहीं है .vimrc, यह केवल कुछ vi(नहीं भी vim) कुंजी संयोजनों का अनुकरण करता है जो शेल में उपयोग किए जा सकते हैं। उसी के बारे में कहा जा सकता है -o emacs, यह पूरी शक्ति के साथ नहीं आता है emacs


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, और इसने मुझे बहुत परेशान किया।


समर्थन को कोसें

bashसमर्थन करता है readline bind। मेरा मानना ​​है कि bashइसके बिना संकलित किया जा सकता है readilneइसलिए कुछ दुर्लभ प्रणालियां हो सकती हैं जिनमें बैश होते हैं जो समर्थन नहीं करते हैं bind(सतर्क रहें)। नक़्शा बनाने के लिए jkकरने के लिए <esc>में bashआप क्या करने की जरूरत:

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

(हाँ यह उद्धृत करने का दोहरा स्तर है, इसकी आवश्यकता है)

फिर, यह टाइपिंग को jकाफी कष्टप्रद बनाता है । लेकिन किसी तरह zshमेरी मशीन पर समाधान की तुलना में कम कष्टप्रद (शायद डिफ़ॉल्ट टाइमआउट कम है)।


वर्कअराउंड (नॉन-बैश और नॉन-ज़श गोले के लिए)

Remapping के लिए कारण Escमहत्वपूर्ण यह है कि यह काफी दूर कीबोर्ड पर दूर है, और टाइप करना यह समय लगता है। एक चाल है कि emacsलोगों से उधार लिया जा सकता है CapsLockक्योंकि यह वैसे भी एक बेकार कुंजी है रीमैप करने के लिए है। emacsलोग इसे रीमैप करते हैं, Ctrlलेकिन हम इसे रीमैप करेंगे Esc

चलो xev -event keyboardकीकोड की जांच करने के लिए उपयोग करते हैं 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फ़ंक्शन को "एस्केप" कहा जाता है। अब हम कर सकते हैं:

# 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

अधिकांश डिस्ट्रोस (वास्तव में प्रदर्शन प्रबंधक, लेकिन मैं सरलता के लिए डिस्ट्रोस कह रहा हूं) द्वारा सम्मानित किया जाना चाहिए, लेकिन मैंने देखा कि वे कई ~/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 सत्र में है, इसलिए नक्शा केवल टर्मिनल emulators में काम करते हैं। वास्तविक ttyनक्शे को नहीं देखेगा।

संदर्भ और अतिरिक्त पढ़ना:


विस्तृत विवरण के लिए धन्यवाद। क्या आप jkइसके बजाय मानचित्रण को छोड़कर उसी प्रक्रिया का वर्णन करने के लिए तैयार होंगे CapsLock? मैंने इसे अपने ओएक्सएक्स मशीन पर सेट किया है; हालाँकि, मेरे पास सप्ताहांत के बाकी दिनों के लिए नहीं है और मुझे याद नहीं है कि मैंने यह कैसे किया :)
mbigras

@mbigras - क्या आप वाकई बैश में यह किया है? बैश में कोई अस्पष्ट नक्शे नहीं हैं। मैं इसे करने का एक तरीका के बारे में पता zsh: bindkey -v; bindkey -s jk \\e। लेकिन यह एक ऐसी चीज है जो वापस आ जाएगी और आपको ज़रूरत पड़ने पर वापस काट देगी jk, क्योंकि टाइमर कॉन्फ़िगर करने योग्य नहीं है और आपके पास में नहीं <leader>है zsh
grochmal

मैंने निश्चित रूप से इसे किया zshऔर नहीं bash, क्या यह बकवास में संभव नहीं है?
mbigras

@mbigras - रुको, मैं गलत था! पढ़ना man bashमैंने पाया bindहै कि काम बहुत के समान zshहै bindkey। मैं जवाब अपडेट कर दूंगा। वहाँ तुम जाओ, मैं zshबहुत अधिक उपयोग कर रहा हूँ ।
grochmal

2
@ जेसन - अरे, यह वीआई एसई है, यहां हर कोई एक शब्द के साथ एक शब्द लिखता है: "टाइप शब्द" <Esc> viwU :)। कोई ज़रूरत पूरी नहीं हुई
grochmal

2

धन्यवाद, पिछले उत्तरों के लिए, मैं अपने टर्मिनल में vi-like शॉर्टकट के लिए अपने ~ / .zshrc में इसका उपयोग करता हूं। मुझे उम्मीद है कि यह किसी की मदद करेगा।

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

मैं यहाँ उत्तर की तलाश में आया था जो vi- सक्षम zsh में "सामान्य मोड" में प्रवेश करने के लिए '^ G' कुंजी को बाँधने के लिए काम करता है, और यह एकमात्र ऐसा काम है।
डल्कर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.