web-dev-qa-db-fra.com

Faites mon mode d'affichage de ZSH en mode VI

J'utilise bindkey -v (pour Bash-ers set -o vi Je pense que cela fonctionne aussi dans ZSH) ou VI (M) en mode. Mais cela me bugs que je n'ai pas de repère visuel pour me dire si je suis en mode insérer ou en mode de commande. Est-ce que quelqu'un sait comment je peux rendre mon invite afficher le mode?

48
xenoterracide

J'ai trouvé ceci via SU . Voici l'exemple de base, même si je le personnifie toujours pour moi-même:

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

Je l'expliquerais sauf que je ne comprends pas encore

25
xenoterracide

Vous avez déjà trouvé zle-keymap-select qui est exécuté chaque fois que le mode change. Vous pouvez l'utiliser pour définir un autre indicateur visuel que l'invite, en fonction de votre prise en charge de votre terminal (et de votre goût d'indicateur de mode en mode, bien sûr).

Il y a une norme Capacité TerminFo Pour changer la forme du curseur. Cependant, certains terminaux affichent le même curseur dans les deux modes. La notion de Xterm d'un curseur moins visible est de le faire clignoter (et cela doit être activé avec le -bc argument de ligne de commande ou cursorBlink ressource).

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

Avec certains terminaux, vous pouvez également modifier la couleur du curseur avec print -n '\e]12;pink\a' (par nom de couleur) ou print -n '\e]12;#abcdef\a' (par spécification RVB). Ces séquences sont décrites dans la documentation Xterm, dans le fichier ctlseqs fichier; Les émulateurs de terminaux modernes émulent généralement Xterm, bien qu'ils ne soutiennent pas toutes ses caractéristiques.

Pour les personnes ayant des problèmes d'utilisation d'invite de réinitialisation avec des invites multilignes, cela a fonctionné pour moi: http://zeitlens.com/posts/2014-06-29-howto-zsh-vi-style.html En combinaison avec https://stackoverflow.com/questions/3622943/zsh-vi-mode-status-line J'ai fini par faire:

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
9
Sebastian Blask

Une autre solution pour changer la forme du curseur entre le faisceau I et le bloc (pour le soulignement, l'utilisation \033[4 q). Ajoutez ceci à votre ~/.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

Modifié à partir de - https://bbs.archlinux.org/viewtopic.php?id=95078 . Testé dans Gnome-Terminal 3.22.


Mettre à jour

Encore une autre solution pour changer les formes du curseur peut être trouvée ici . Celui-ci fonctionne apparemment pour ITERM2, que je n'ai pas les moyens de tester, mais en l'ajoutant ici au cas où il est utile pour quelqu'un d'autre. L'ajout final à votre ~/.zshrc serait

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
6
joelostblom

vous pouvez essayer vimmode

5
Hemant

Voici une autre version, basée à partir de Sebastian Block's Post . Ceci était destiné à être aussi non intrusif possible, car toutes les autres solutions que je pouvais trouver des lignes supplémentaires utilisées, un statut à droite ou des caractères ajoutés.

Cela change simplement la couleur de $ du blanc au rouge lorsque le mode normal est activé. Modifier l'invite à votre goût

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
3
sealj553

J'utilise actuellement ZSH avec Train Bullet Thème. Après l'exemple donné par Réponse de Sebastian Block , j'ai fini par le code ci-dessous.

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

Cela ne changera que DEFAULT $ aux lettres [~ # ~] n [~ # ~] en mode normal et [~ # ~] i [~ # ~] Pour insérer le mode.

Cette image est un exemple quand en mode normal I appuyez sur Ctrl+C:

enter image description here

3
Luciano Almeida

Une version pour oh-my-zsh utilisateurs

Il y a un plugin pour oh-my-zsh appelé vi-mode qui peut être trouvé ici:

RobbyRussell/OH-My-ZSH/Plugins/VI-Mode

J'utilise un antigène pour gérer mes plug-ins, y compris celui-ci était aussi simple que d'ajouter cela à mon .zshrc:

antigen bundle vi-mode
2
Jonathan Landrum

Le plugin ZSH-VIM-MODE est capable d'afficher un indicateur d'insertion, de commande, de recherche, de remplacement et de modes visuels. Il utilise la technique de base d'autres réponses à accrocher aux différents crochets ZLE (ZLE-KEYMAP-SELECT, ZLE-ISearch-Update, etc.). Il vérifie [[ $ZLE_STATE = *overwrite* ]] pour le mode Remplacer. Il vérifie $REGION_ACTIVE Pour identifier le mode visuel.

La logique est compliquée par quelques bizarreries de la façon dont ZSH incendie les événements lors de la sortie du mode ISearch.

Une autre caractéristique intéressante du module est la possibilité de changer la forme du curseur et la couleur en fonction du mode. Par exemple, vous pouvez utiliser une barre verticale en mode insertion et un soulignement clignotant en mode de recherche.

1
Tim Smith