vi मोड में मेरे zsh प्रॉम्प्ट शो मोड बनाएं


44

मैं उपयोग करता हूं bindkey -v(bash-ers के लिए set -o viमुझे लगता है कि zsh में भी काम करता है) या vi (m) मोड। लेकिन यह मुझे बताता है कि मेरे पास यह बताने के लिए कोई दृश्य क्यू नहीं है कि क्या मैं इन्सर्ट मोड या कमांड मोड में हूँ। क्या किसी को पता है कि मैं अपने प्रॉम्प्ट को कैसे प्रदर्शित कर सकता हूं?

जवाबों:


25

मुझे यह एसयू के माध्यम से मिला । यहाँ मूल उदाहरण है, हालाँकि मैं अभी भी इसे अपने लिए अनुकूलित कर रहा हूँ:

function zle-line-init zle-keymap-select {
    RPS1="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}"
    RPS2=$RPS1
    zle reset-prompt
}

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

मैं इसे समझाता हूँ सिवाय इसके कि मैं वास्तव में इसे अभी तक नहीं समझ पाया हूँ


1
मैंने इस दृष्टिकोण की कोशिश की, लेकिन एक मुद्दा मिला। यदि आप CTRL+Cvi-कमांड मोड में रहते हुए कुछ करते हैं, तो प्रॉम्प्ट रीसेट हो जाएगा, लेकिन जब आप वास्तव में इन्सर्ट मोड में हैं, तो आप कमांड मोड में संकेत देते हैं। zle-line-initहमेशा मोड डालने के लिए संकेतक को बदलना चाहिए। $KEYMAPजब किसी कारणवश zle-line-init को ठीक से अपडेट नहीं किया जाता है।
पैट्रिक

2
zle reset-promptफिर से
लाल करने पर

@ PawełGo Pawcicki यह एक मुद्दा लगता है जब आपके पास PS1 की दो या अधिक लाइनें होती हैं।
मेटाफॉक्स

@Metaphox मुझे पता है, कि मैंने क्यों कहा है "(यदि आपका संकेत बहु है)"। उसके लिए कोई फिक्स?
पावेल गोइस्की

@ PawełGo Pawcicki aww माफ करना मैं किसी तरह कोष्ठक, बुरी आदत में शब्दों को छोड़ दिया। नहीं, मुझे इसके लिए कोई फिक्स नहीं मिला। आप किस मंच पर हैं? सोच रहा था कि क्या यह ओएस एक्स विशिष्ट है।
मेटाफॉक्‍स

18

zle-keymap-selectजब भी मोड परिवर्तित होता है, तो आपको पहले ही मिल चुका होता है। आप इसका उपयोग प्रॉम्प्ट की तुलना में कुछ अन्य दृश्य संकेतक सेट करने के लिए कर सकते हैं, यह इस बात पर निर्भर करता है कि आपका टर्मिनल इसका समर्थन करता है (और मोड संकेतक डिस्प्ले में आपका स्वाद, निश्चित रूप से)।

कर्सर के आकार को बदलने के लिए एक मानक टर्मिनो क्षमता है। हालाँकि कुछ टर्मिनल दोनों मोड में एक ही कर्सर प्रदर्शित करते हैं। कम दृश्यमान कर्सर की Xterm की धारणा इसे पलक बनाने के लिए है (और इसे -bcकमांड लाइन तर्क या cursorBlinkसंसाधन के साथ सक्षम होना चाहिए )।

zle-keymap-select () {
  case $KEYMAP in
    vicmd) print -rn -- $terminfo[cvvis];; # block cursor
    viins|main) print -rn -- $terminfo[cnorm];; # less visible cursor
  esac
}

कुछ टर्मिनलों के साथ, आप कर्सर का रंग print -n '\e]12;pink\a'(रंग के नाम से) या print -n '\e]12;#abcdef\a'(RGB विनिर्देश द्वारा ) भी बदल सकते हैं । ये क्रम xterm प्रलेखन में, ctlseqsफ़ाइल में वर्णित हैं ; आधुनिक टर्मिनल एमुलेटर आमतौर पर एक्सटर्म का अनुकरण करते हैं, हालांकि वे इसकी सभी विशेषताओं का समर्थन नहीं कर सकते हैं।


किसी कारण से मैं mainके लिए KEYMAPके बजाय viins, यकीन है कि क्यों नहीं।
ग्रीम

1
@Gememe के mainलिए एक उपनाम है viinsया emacsनिर्भर करता है कि क्या zsh ने सोचा कि आपका पसंदीदा संपादक vi था या नहीं जब यह शुरू हुआ था। मुझे लगा कि viinsमोड को वापस से स्विच करने पर इसका उपयोग होगा vicmd, लेकिन ऐसा लगता है कि यह mainइसके बजाय उपयोग करता है । अपडेट किया गया।
गिलेस एसओ- बुराई को रोकना '

1
आपको अभी भी zle-line-init(या जो भी वैकल्पिक) के साथ दोगुना करने की आवश्यकता है क्योंकि zle-keymap-selectअगर कीमैप में परिवर्तन दर्ज नहीं किया जाता है तो कॉल नहीं किया जाता है।
ग्रीम

9

मल्टीलाइन प्रॉम्प्ट के साथ रीसेट-प्रॉम्प्ट का उपयोग करने वाले लोगों के लिए, यह मेरे लिए काम करता है: http://zeitlens.com/posts/2014-06-29-howto-zsh-vi-style.html https के साथ संयोजन में : // stackoverflow.com/questions/3622943/zsh-vi-mode-status-line मैंने काम करना समाप्त कर दिया:

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]

function insert-mode () { echo "-- INSERT --" }
function normal-mode () { echo "-- NORMAL --" }

precmd () {
    # yes, I actually like to have a new line, then some stuff and then 
    # the input line
    print -rP "
[%D{%a, %d %b %Y, %H:%M:%S}] %n %{$fg[blue]%}%m%{$reset_color%}"

    # this is required for initial prompt and a problem I had with Ctrl+C or
    # Enter when in normal mode (a new line would come up in insert mode,
    # but normal mode would be indicated)
    PS1="%{$terminfo_down_sc$(insert-mode)$terminfo[rc]%}%~ $ "
}
function set-prompt () {
    case ${KEYMAP} in
      (vicmd)      VI_MODE="$(normal-mode)" ;;
      (main|viins) VI_MODE="$(insert-mode)" ;;
      (*)          VI_MODE="$(insert-mode)" ;;
    esac
    PS1="%{$terminfo_down_sc$VI_MODE$terminfo[rc]%}%~ $ "
}

function zle-line-init zle-keymap-select {
    set-prompt
    zle reset-prompt
}
preexec () { print -rn -- $terminfo[el]; }

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

5

आप VimMode की कोशिश कर सकते हैं


4
मैं कुछ कम कड़ी और कुछ अधिक व्याख्यात्मक के लिए उम्मीद कर रहा था। मुझे यह जानना पसंद है कि चीजें कैसे काम करती हैं।
xenoterracide

1
वास्तव में यह सब कुछ है। टिप्पणियों के कार्यों को देखें और वे मोड परिवर्तन की घटनाओं के लिए कैसे बाध्य हैं।
मार्टिन

5

यह वह है जो मैं 'ब्लॉक' और 'बीम' आकार के बीच कर्सर को zsh में बदलने के लिए उपयोग करता हूं:

( दीमक , सूक्ति-टर्मिनल और मेट-टर्मिनल के साथ परीक्षण )

# vim mode config
# ---------------

# Activate vim mode.
bindkey -v

# Remove mode switching delay.
KEYTIMEOUT=5

# Change cursor shape for different vi modes.
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] ||
     [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'

  elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]] ||
       [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

# Use beam shape cursor on startup.
echo -ne '\e[5 q'

# Use beam shape cursor for each new prompt.
preexec() {
   echo -ne '\e[5 q'
}

यह केवल टर्मिनलों और टर्मिनल एमुलेटर पर काम करेगा जो DECSCUSR को समझते हैं।
JdeBP

1
मुझे यह पसंद हे। मुझे चिंता है कि preexec पर लिखना अन्य उपयोगों के साथ बातचीत कर सकता है, इसलिए मैंने इसका उपयोग करने के लिए इसे थोड़ा संशोधित किया add-zsh-hook: gist.github.com/MatrixManAtYrService/…
MatrixManAtYrService

4

आई-बीम और ब्लॉक (अंडरस्कोर, उपयोग के लिए \033[4 q) के बीच कर्सर का आकार बदलने के लिए एक और समाधान । इसे अपने में जोड़ें ~/.zshrc

zle-keymap-select () {
if [ $KEYMAP = vicmd ]; then
    printf "\033[2 q"
else
    printf "\033[6 q"
fi
}
zle -N zle-keymap-select
zle-line-init () {
zle -K viins
printf "\033[6 q"
}
zle -N zle-line-init
bindkey -v

Https://bbs.archlinux.org/viewtopic.php?id=95078 से संशोधित । सूक्ति-टर्मिनल 3.22 में परीक्षण किया गया।


अपडेट करें

फिर भी कर्सर के आकार को बदलने का एक और समाधान यहां पाया जा सकता है । यह एक जाहिरा तौर पर iTerm2 के लिए काम करता है, जिसका मेरे पास परीक्षण करने का साधन नहीं है, लेकिन इसे किसी और के लिए उपयोगी होने पर इसे यहां जोड़ना है। आपके लिए अंतिम जोड़ ~/.zshrcहोगा

function zle-keymap-select zle-line-init
{
    # change cursor shape in iTerm2
    case $KEYMAP in
        vicmd)      print -n -- "\E]50;CursorShape=0\C-G";;  # block cursor
        viins|main) print -n -- "\E]50;CursorShape=1\C-G";;  # line cursor
    esac

    zle reset-prompt
    zle -R
}

function zle-line-finish
{
    print -n -- "\E]50;CursorShape=0\C-G"  # block cursor
}

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

1
मैंने पुष्टि की कि iTerm2 के लिए अद्यतन स्क्रिप्ट वास्तव में काम की है।
जेसन डेनी

पहली स्क्रिप्ट केवल टर्मिनलों और टर्मिनल एमुलेटर पर काम करेगी जो DECSCUSR को समझती है।
JdeBP

यह एक बहुत ही सुंदर समाधान है जो मेरे खोल को बंद नहीं करता है
tsturzl

3

मैं वर्तमान में बुलेट ट्रेन थीम के साथ Zsh का उपयोग कर रहा हूं । सेबेस्टियन ब्लास्क के जवाब द्वारा दिए गए उदाहरण के बाद , मैंने कोड बोले के साथ समाप्त किया

bindkey -v
KEYTIMEOUT=1

function zle-line-init zle-keymap-select {
    case ${KEYMAP} in
        (vicmd)      BULLETTRAIN_PROMPT_CHAR="N" ;;
        (main|viins) BULLETTRAIN_PROMPT_CHAR="I" ;;
        (*)          BULLETTRAIN_PROMPT_CHAR="I" ;;
    esac
    zle reset-prompt
}

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

यह केवल N अक्षर को सामान्य मोड और I को मोड में डालने के लिए डी डिफ़ॉल्ट $ को बदल देगा ।

यह छवि एक उदाहरण है जब सामान्य मोड में मैं Ctrl+ दबाता हूं C:

यहाँ छवि विवरण दर्ज करें


2

सेबस्टियन ब्लास्क के पोस्ट के आधार पर यहां एक और संस्करण है । यह जितना संभव हो उतना गैर-दखल देने का इरादा था, क्योंकि अन्य सभी समाधान मैं इस्तेमाल की गई अतिरिक्त लाइनें, दाईं ओर स्थिति, या जोड़े गए वर्ण पा सकते थे।

यह $सामान्य मोड सक्षम होने पर बस सफेद से लाल रंग में बदल जाता है। अपनी पसंद के अनुसार शीघ्र संपादित करें

bindkey -v
function zle-line-init zle-keymap-select {
    case ${KEYMAP} in
        (vicmd)      PROMPT=$'%{\e[0;32m%}%~%{\e[0m%} %{\e[0;31m%}$%{\e[0m%} ' ;;
        (main|viins) PROMPT=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
        (*)          PROMPT=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
    esac
    zle reset-prompt
}

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

2

oh-my-zshउपयोगकर्ताओं के लिए एक संस्करण

oh-my-zshकहा जाता है vi-modeकि यहाँ पाया जा सकता है के लिए एक प्लगइन है:

robbyrussell / ओह-मेरी-zsh / plugins / vi मोड

मैं अपने प्लगइन्स को प्रबंधित करने के लिए एंटीजन का उपयोग करता हूं, इसलिए इसमें मेरे लिए इसे जोड़ना जितना आसान था .zshrc:

antigen bundle vi-mode

1

Zsh-vim-मोड प्लगइन डालने, आदेश, खोज, की जगह है, और दृश्य मोड के लिए एक संकेतक को दिखाने के लिए सक्षम है। यह विभिन्न ZLE हुक (zle-keymap-select, zle-isearch-update, आदि) को हुक करने के लिए अन्य उत्तरों की मूल तकनीक का उपयोग करता है। यह [[ $ZLE_STATE = *overwrite* ]]प्रतिस्थापित मोड के लिए जाँच करता है। यह $REGION_ACTIVEदृश्य मोड की पहचान करने के लिए जाँच करता है।

तर्क खोज मोड से निकलते समय ZSH की घटनाओं को कैसे भड़काती है, इसके कुछ सवालों से तर्क जटिल है।

मॉड्यूल की एक और अच्छी विशेषता कर्सर के आकार और रंग को मोड के आधार पर बदलने की क्षमता है। उदाहरण के लिए, आप INSERT मोड में वर्टिकल बार और SEARCH मोड में ब्लिंकिंग अंडरलाइन का उपयोग कर सकते हैं।


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