मैं zsh के vim मोड को कैसे अनुकूलित करूं?


25

ठीक है, इसलिए मैंने आखिरकार महान बदलाव किया। मेरे। ज़ेनसेव में, मैंने अपना EDITOR बदल दिया:

export EDITOR=vim

मेरे पास कुछ सवाल हैं जो इतने मामूली हैं कि मैं उनके लिए अलग सवाल शुरू नहीं करना चाहता। वे यहाँ हैं:

  1. विम और जैसे मोड में कमांड मोड के बीच अंतर करने के लिए मुझे zsh कैसे मिलता है? अधिमानतः यह कर्सर को अंडरलाइन से ब्लॉक में विम की तरह बदल देगा, लेकिन तल पर पाठ प्रदर्शित करना भी काम करेगा।

  2. मैं इसे विम की तरह अधिक अभिनय करने के लिए कैसे प्राप्त करूं? उदाहरण के लिए, मैं इसे डिफ़ॉल्ट रूप से कमांड मोड में रखूंगा और एक कमांड के बाद इसके बाहर नहीं जाऊंगा।


//, क्या आपको कमांड-लाइन संपादन के साथ कोई अजीब व्यवहार हो रहा है? ~जब मैं Deleteकुंजी को दबाता हूं तो मैं उस चरित्र में सम्मिलित होता हूं zsh। मैंने इसके बारे में एक प्रश्न पूछा था: superuser.com/questions/997593/…
नाथन बसानी

जवाबों:


25

1. ) (देखें http://zshwiki.org/home/examples/zlewidgets और http://pthree.org/2009/03/28/add-vim-editing-mode-to-your-zsh-prompt/ ) :

समारोह zle-line-init zle-keymap-select {
    RPS1 = "$ {$ {KEYMAP / vicmd / - NORMAL -} / ((मुख्य - viins) / - INSERT -}"
    RPS2 = $ RPS1
    zle रीसेट-प्रॉम्प्ट
}
zle -N zle-line-init
zle -N zle-keymap-select

कहा पे:

  • "RPS" का अर्थ है 'राइट प्रॉम्प्ट स्ट्रिंग' और टर्मिनल के दाहिने हाथ की तरफ दिखने वाले प्रॉम्प्ट को परिभाषित करता है, और $ {वैरिएबल / पैटर्न / रिप्लेसमेंट} सिंटैक्स 'पैरामीटर विस्तार' का है, देखें: http: // mywiki .wooledge.org / BashSheet # पैरामीटर_परेशन

  • 'zle -N' उपयोगकर्ता-निश्चित विजेट्स 'zle-line-init' और 'zle-keymap-select' को बाध्य करता है (समान नामों के शेल कार्यों के लिए), जिससे उन्हें तब बुलाया जाएगा जब लाइन संपादक को आरंभीकृत किया जाता है और कीमैप को क्रमशः बदला गया है, देखें: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#SEC125

2. ) मुझे संदेह है कि आपको ऐसा करने के लिए एक और zsh- विजेट लिखना होगा, पहली समस्या के लिए दो लिंक से प्रेरित हों।


22

मल्टी-लाइन प्रॉम्प्ट का उपयोग करते समय अकीरा के समाधान में निम्नलिखित समस्या होती है: जब ins से cmd मोड पर जा रहे होते हैं, तो प्रॉम्प्ट redraw कुछ पंक्तियों को पिछले आउटपुट से हटा देता है (और नई प्रॉम्प्ट ऊपर कुछ पंक्तियाँ प्रदर्शित होती है)। कितनी लाइनें इस बात पर निर्भर करती हैं कि आपके प्रॉम्प्ट में कितनी लाइनें हैं।

वहां से निपटने का तरीका है zle-line-finish, बिना उपयोग किए zle reset-prompt। एक उदाहरण:

# perform parameter expansion/command substitution in prompt
setopt PROMPT_SUBST

vim_ins_mode="[INS]"
vim_cmd_mode="[CMD]"
vim_mode=$vim_ins_mode

function zle-keymap-select {
  vim_mode="${${KEYMAP/vicmd/${vim_cmd_mode}}/(main|viins)/${vim_ins_mode}}"
  zle reset-prompt
}
zle -N zle-keymap-select

function zle-line-finish {
  vim_mode=$vim_ins_mode
}
zle -N zle-line-finish

और फिर आप इसे अपने राइट-प्रॉम्प्ट में जोड़ सकते हैं, उदाहरण के लिए:

RPROMPT='${vim_mode}'

यह सीधे मेरे ब्लॉग पोस्ट से इसके बारे में है:


इस जवाब को बहुत सारे वोट मिलने चाहिए। यह पहली बार है जब मैंने इस समाधान को देखा है, और यह काम करता है जहां अन्य नहीं करते हैं। मैंने zle-line-initकोई लाभ नहीं होने के लिए विजेट के साथ एक घंटे के आसपास चक्कर लगाया । इसे बदलने के लिए जो पावेल ने प्रदान किया और बिंगो को दिया!
कॉलिन आर

धन्यवाद! यह अभी भी 100% बुलेटप्रूफ नहीं है - समय-समय पर मैं ऐसी स्थिति का अनुभव करता हूं जहां मेरे पिछले आउटपुट से कुछ लाइनें हटा दी जाती हैं - लेकिन ऐसा बहुत कम ही होता है कि मैं इसे अनदेखा करूं।
पावेल गोइस्की

1
RPROMPT2साथ ही सेट किया जाना चाहिए ताकि स्थिति निरंतरता रेखाओं में प्रदर्शित हो। इसके अलावा, इसका उपयोग करते समय आप ऐसा करना चाह सकते हैं setopt transient_rpromptताकि पहले स्वीकृत लाइनों के लिए मोड प्रदर्शित न हों।
15

एक चीज जो अभी भी गायब है: अगर मैं एमएसीएस मोड पर वापस स्विच करता हूं ( bindkey -e) यह अभी भी दिखाता है [INS]
डैनियल

1
@cheflo आप इस सेटअप के मेरे वर्तमान संस्करण को यहां देख सकते हैं: github.com/pjg/dotfiles/blob/master/.zshrc#L518-L584 - शायद इससे आपको मदद मिलेगी
Paweł Gocicki

5
zle-line-init() { zle -K vicmd; }
zle -N zle-line-init

यह दो पंक्तियाँ सुनिश्चित करती हैं कि यह कमांड मोड में शुरू हो


काम नहीं करता है, वैसे भी इन्सर्ट मोड में zsh शुरू होता है
बाल्डर्स

0

नीचे आपको एक संशोधित कर्सर और एक शीघ्र प्रदर्शित करने के साथ सेट किया जाएगा कि आप किस मोड में हैं। आप या DEFAULT_VI_MODEतो बदल सकते हैं । बस शुरू करने के लिए नीचे एक ताजा पेस्ट करें :viinsvicmd.zshrc

# Prefer vi shortcuts
bindkey -v
DEFAULT_VI_MODE=viins
KEYTIMEOUT=1

__set_cursor() {
    local style
    case $1 in
        reset) style=0;; # The terminal emulator's default
        blink-block) style=1;;
        block) style=2;;
        blink-underline) style=3;;
        underline) style=4;;
        blink-vertical-line) style=5;;
        vertical-line) style=6;;
    esac

    [ $style -ge 0 ] && print -n -- "\e[${style} q"
}

# Set your desired cursors here...
__set_vi_mode_cursor() {
    case $KEYMAP in
        vicmd)
          __set_cursor block
          ;;
        main|viins)
          __set_cursor vertical-line
          ;;
    esac
}

__get_vi_mode() {
    local mode
    case $KEYMAP in
        vicmd)
          mode=NORMAL
          ;;
        main|viins)
          mode=INSERT
          ;;
    esac
    print -n -- $mode
}

zle-keymap-select() {
    __set_vi_mode_cursor
    zle reset-prompt
}

zle-line-init() {
    zle -K $DEFAULT_VI_MODE
}

zle -N zle-line-init
zle -N zle-keymap-select

# Optional: allows you to open the in-progress command inside of $EDITOR
autoload -Uz edit-command-line
bindkey -M vicmd 'v' edit-command-line
zle -N edit-command-line

# PROMPT_SUBST enables functions and variables to re-run everytime the prompt
# is rendered
setopt PROMPT_SUBST

# Single quotes are important so that function is not run immediately and saved
# in the variable
RPROMPT='$(__get_vi_mode)'

नोट: मैंने इसे केवल Mac.OS पर टर्मिनल.app (2.7.3) (10.12.6) में zsh (5.3.1) के साथ परीक्षण किया। इसके अलावा, यदि आप कभी भी जोड़ते हैं edit-command-lineतो मोड सही ढंग से सेट हो जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.