benim zsh istemi göstermek modu vi modunda yapmak


44

Kullandığım bindkey -v(bash-ERS için set -o viveya vi (m) modunu O zsh içinde çalışmalarını da düşünüyorum). ancak bu, ekleme modunda mı yoksa komut modunda mı olduğumu söyleyecek görsel bir ipucum olmadığı için beni rahatsız ediyor. İstemi modumu nasıl gösterebileceğimi bilen var mı?

Yanıtlar:


25

Bulduğum bu aracılığıyla SU . İşte temel örnek, yine de kendim için özelleştiriyorum:

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

Bunu henüz anlayamadığım dışında açıklarım.


1
Bu yaklaşımı denedim ama bir sorun buldum. CTRL+CVi-komut modundayken gibi bir şey yaparsanız , komut istemi sıfırlanır, ancak gerçekten ekleme modundayken komut modunda olduğunuzu gösterir. zle-line-inither zaman göstergeyi ekleme moduna getirmeli. Bir nedenle $KEYMAP, zle-line-init çağrıldığında düzgün şekilde güncellenmez.
Patrick

2
zle reset-prompt(satırlı senin istemi ise) yeniden çizilmesi sırasında istemi yukarıdaki satırları (daha fazla veya) 1 silecektir :( Bu bir showstopper benim için.
Pawel Gościcki

@ PawełGościcki iki veya daha fazla PS1 hattınız olduğunda bu bir sorun gibi görünüyor.
Metaforks

@Metaphox Biliyorum, bu yüzden "(isteminiz multiline ise)" dedim. Bunun için herhangi bir düzeltme var mı?
Paweł Gościcki

@ PawełGościcki aww üzgünüm ben bir şekilde parantez içindeki sözcükleri atladım, kötü alışkanlık. Hayır, bunun için bir düzeltme bulamadım. Hangi platformdasın? Bunun OS X'e özgü olup olmadığını merak ediyordum.
Metaphox

18

zle-keymap-selectMod değiştiğinde hangisinin yürütüldüğünü zaten buldunuz. Terminalinizin neyi desteklediğine bağlı olarak, istemden başka bir görsel gösterge ayarlamak için kullanabilirsiniz (ve tabii ki mod göstergesi ekranındaki zevkiniz).

İmlecin şeklini değiştirmek için standart bir terim özelliği vardır . Ancak bazı terminaller aynı imleci her iki modda da görüntüler. Xterm'in daha az görünür bir imleç kavramı, yanıp sönmesini sağlamaktır (ve bu -bckomut satırı argümanı veya cursorBlinkkaynak ile etkinleştirilmelidir ).

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

Bazı terminallerde imleç rengini print -n '\e]12;pink\a'(renk adına göre) veya print -n '\e]12;#abcdef\a'(RGB özelliklerine göre) de değiştirebilirsiniz. Bu diziler, ctlseqsdosyadaki xterm belgelerinde açıklanmaktadır ; modern terminal emülatörleri, tipik olarak tüm özelliklerini desteklemese de, xterm'i taklit eder.


Nedense bunun mainiçin olsun , neden emin değilim. KEYMAPviins
Graeme

1
@Graeme mainbir takma içindir viinsveya emacsolmamasına bağlı olarak zsh düşünce Ne zaman başladığını favori editörü vi veya değildi. viinsModu geri döndürürken kullanacağını düşündüm vicmd, ama onun mainyerine kullandığı görülüyor . Güncellenmiş.
Gilles 'SO- kötülük olmayı bırak'

1
Yine de zle-line-init(veya ne olursa olsun alternatif) ikiye katlamanız gerekiyor çünkü zle-keymap-selectenter'a basılması tuş haritasını değiştirdiğinde çağrılmaz.
Graeme

9

Çok satırlı komut istemiyle reset komut istemini kullanmada sorun yaşayan insanlar için bu işe yaradı: http://zeitlens.com/posts/2014-06-29-howto-zsh-vi-style.html https: // ile birlikte stackoverflow.com/questions/3622943/zsh-vi-mode-status-line Yapmayı bitirdim:

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'u deneyebilirsiniz


4
Daha az bağlayıcılı ve biraz daha açıklayıcı bir şey umuyordum. İşlerin nasıl yürüdüğünü bilmek hoşuma gidiyor.
xenoterracide

1
Aslında hepsi orada. Yorumlara, fonksiyonlara ve bunların mod değiştirme olaylarına nasıl bağlı olduklarına bakın.
Martin

5

İmleci zsh'de 'Block' ve 'Beam' şekli arasında değiştirmek için kullandığım şey:

( Termit , GNOME terminali ve Mate Terminali ile test edilmiştir )

# 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'
}

Bu sadece DECSCUSR'yi anlayan terminaller ve terminal emülatörleri üzerinde çalışacaktır.
JdeBP

1
Bunu severim. Ben biraz kullanmak üzere modifiye yüzden, diğer kullanımlar ile preexec kudreti etkileştiği için bu yazıyı endişelenmeyin add-zsh-hook: şöyle gist.github.com/MatrixManAtYrService/...
MatrixManAtYrService

4

I-beam ve blok arasındaki imleç şeklini değiştirmek için başka bir çözüm (alt çizgi için, kullanın \033[4 q). Bunu da ekle ~/.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 adresinden değiştirilmiştir . GNOME-terminal 3.22'de test edilmiştir.


Güncelleme

İmleç şekillerini değiştirmeye yönelik başka bir çözüm burada bulunabilir . Bu, görünüşe göre test etme imkanım olmadığı iTerm2 için çalışıyor, ancak başkası için yararlı olması durumunda buraya eklenmesi. Son eklenen ~/.zshrcşey

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
İTerm2 için güncellenmiş betiğin gerçekten işe yaradığını onayladım.
Jason Denney

İlk senaryo yalnızca DECSCUSR'yi anlayan terminaller ve terminal emülatörleri üzerinde çalışacaktır.
JdeBP

Bu benim kabuğumu karıştırmaz, gerçekten şık bir çözüm
tsturzl

3

Şu anda Bullet Train temasıyla Zsh kullanıyorum . Tarafından verilen örnek ardından Sebastian blask cevabı , ben kod ile sona erdi feryat

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

Bu yalnızca de varsayılan değişecek $ harflere N normal moda ve ben ekleme moduna.

Bu görüntü normal modda Ctrl+ tuşuna basarken bir örnektir C:

görüntü tanımını buraya girin


2

İşte Sebastian Blask'un gönderisine dayanarak başka bir versiyon daha . Bu, bulabildiğim diğer tüm çözümler kadar sağlayıcılığa aykırı olması, kullanılan ekstra satırları, sağdaki durumu veya eklenmiş karakterleri bulabilmesi için tasarlanmıştı.

$Normal mod etkinleştirildiğinde bu sadece beyazdan kırmızıya rengini değiştirir . İsteme isteminizi düzenleyin

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-zshKullanıcılar için bir sürüm

İçin bir eklenti var oh-my-zshdenilen vi-modeburada bulunabilir:

robbyrussell / oh-my-zsh / plugins / vi mod

Ben bu yüzden kardeşime karşı bu ekleme gibi basit gibiydi dahil benim eklentileri yönetmek için Antigen kullanın .zshrc:

antigen bundle vi-mode

1

Zsh-vim modu eklentisi eki, komuta, arama, değiştirme ve görsel modları için bir gösterge göstermek yapabiliyor. Çeşitli ZLE kancalarına (zle-keymap-select, zle-isearch-update, vb.) Bağlanmak için diğer cevapların temel tekniğini kullanır. [[ $ZLE_STATE = *overwrite* ]]Değiştirme modunu kontrol eder . $REGION_ACTIVEGörsel modu tanımlamak için kontrol eder .

Mantık, ZSH'nin isearch modundan çıkarken olayları nasıl ateşlediğine dair bazı tuhaflıklar ile karmaşıktır.

Modülün bir diğer güzel özelliği de, imleci şekil ve rengi moda göre değiştirme yeteneği. Örneğin, INSERT modunda dikey bir çubuk ve ARAMA modunda yanıp sönen bir alt çizgi kullanabilirsiniz.


Bu eklenti harika.
Jdhao
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.