Comment rechercher / grep de manière interactive avec VIM?

12

Existe-t-il un moyen de configurer VIM pour rechercher de manière interactive dans chaque fichier un projet entier?

Par interactif , je veux dire mettre à jour chaque frappe.

Quelque chose comme Emacs Counsel-Git-Grep , voir: exemple de démo .

ideasman42
la source
Je ne l'utilise pas personnellement, donc je ne suis pas sûr à 100%, mais je pense ctrl-pqu'un plugin similaire est ce que vous recherchez. Notez que cela unite.vimdevrait également être en mesure de le faire, mais je ne le recommanderais pas car à mon avis, c'est un plugin assez lourd et créateur de bogues.
statox
Existe ctrl-p- t -il un moyen de rechercher de manière interactive le contenu du fichier? Je ne l'ai utilisé que pour rechercher de manière interactive des fichiers en fonction de leurs noms.
ideasman42
Je pense que c'est possible mais comme je l'ai dit je ne l'utilise pas alors peut-être que je me trompe
statox

Réponses:

14

Je ne suis pas sûr que ce soit ce que vous recherchez, mais vous pourriez peut-être essayer fzf et fzf.vim .

Si vous utilisez vim-plug comme gestionnaire de plugins, tout ce que vous devez faire pour les installer est d'ajouter ces lignes dans votre vimrc:

Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'

... quelque part entre les lignes:

call plug#begin('~/.vim/plugged')

et:

call plug#end()

Exécutez ensuite :PlugInstall.


Parmi les différentes commandes et mappages fournis par fzf.vim(dont le seul but semble être d'installer des mappages et des commandes demandant fzfune recherche floue à travers des sources prédéfinies), il y a la commande :Ag.

Pour pouvoir l'utiliser, vous devez installer la commande shell ag . Sur les distributions basées sur Debian, cela peut être fait avec la commande suivante:

apt-get install silversearcher-ag

Le projet sur github explique comment l'installer sur MacOS:

brew install the_silver_searcher

:Agest un wrapper autour $ ag, et vous permet de rechercher de façon floue un modèle dans les fichiers du répertoire courant (celui affiché lorsque vous tapez :pwd). Les correspondances sont mises à jour après chaque frappe.

Vous pouvez:

  • avancer et reculer dans les matchs avec C-netC-p
  • sélectionner la correspondance actuelle et passer à la suivante / précédente avec Tab/S-Tab
  • sélectionner ou désélectionner toutes les correspondances avec M-aouM-d

Si vous sélectionnez une ou plusieurs correspondances, après avoir appuyé sur Entrée, elles rempliront la liste des correctifs. De là, vous pourrez les parcourir avec les commandes / mappages Vim par défaut, tels que :cnextet :cprevious.

entrez la description de l'image ici

Si vous souhaitez ajouter un préfixe à toutes les commandes installées par fzf.vimet éviter de remplacer les commandes existantes, vous pouvez l'ajouter dans votre vimrc:

let g:fzf_command_prefix = 'your_prefix'

J'utilise Fzfcomme préfixe, c'est pourquoi je n'ai pas tapé :Agmais :FzfAg.


Si vous préférez utiliser à la git grepplace de ag, il semble que vous puissiez installer votre propre wrapper personnalisé autour de lui :GGrep, comme ceci:

command! -bang -nargs=* GGrep
  \ call fzf#vim#grep('git grep --line-number '.shellescape(<q-args>), 0, <bang>0)

C'est expliqué dans :h fzf-vim-customization.

En outre, si fzfouvre une fenêtre dans tmux, et vous préférez qu'il faut tout l'écran à la place, vous pouvez ajouter un coup à toutes les commandes ( :Ag!, :GGrep!...).


Comme vous l'avez dit dans votre dernier commentaire , fzfchange par défaut la configuration de votre shell. Par exemple, si vous utilisez bash, cela ajoutera la ligne suivante dans votre ~/.bashrc:

[ -f ~/.fzf.bash ] && source ~/.fzf.bash

Cela source le fichier ~/.fzf.bash. Ce dernier contient du code:

# Setup fzf
# ---------
if [[ ! "$PATH" == */home/user/.fzf/bin* ]]; then
  export PATH="$PATH:/home/user/.fzf/bin"
fi

# Auto-completion
# ---------------
[[ $- == *i* ]] && source "/home/user/.fzf/shell/completion.bash" 2> /dev/null

# Key bindings
# ------------
source "/home/user/.fzf/shell/key-bindings.bash"

Ce code ajoute un chemin d' accès à la variable d'environnement $PATH: /home/user/.fzf/bin; qui est le dossier contenant le fzfprogramme.

Il source également 2 autres fichiers:

/home/user/.fzf/shell/completion.bash
/home/user/.fzf/shell/key-bindings.bash

Le premier semble définir des fonctions d'achèvement, tandis que le second installe des raccourcis clavier.

Malheureusement, les raccourcis clavier peuvent remplacer les readlinefonctions par défaut .
Par exemple, fzflie la fonction fzf-file-widgetà C-t. Cette clé est généralement utilisée par readline pour exécuter la transpose-charsfonction.

Si vous ne le souhaitez pas, une solution possible serait de restaurer les raccourcis clavier à l'intérieur de votre ~/.bashrc, après fzfavoir obtenu sa configuration. Par exemple, si vous vouliez C-tconserver son ancien comportement, c'est-à-dire transposer les 2 caractères autour du curseur, et lier fzf-file-widgetà une autre clé, disons C-x C-t, vous pourriez ajouter ces lignes à la fin de ~/.bashrc:

bind -x '"\C-x\C-t": fzf-file-widget'
bind '"\C-t": transpose-chars'

La même chose s'applique au zshshell, mais la syntaxe pour installer une liaison de clé est un peu différente:

bindkey '^X^T' fzf-file-widget
bindkey '^T' transpose-chars

Si l'une des liaisons de touches du shell auxquelles vous étiez habitué a été remplacée fzf, vous voulez la restaurer, mais vous ne savez pas quel est le nom exact de la fonction qui a été exécutée, vous pouvez essayer la chose suivante.

Tout d'abord, à l'intérieur de votre ~/.bashrc, mettez temporairement en commentaire la ligne source de la fzfconfiguration. Ensuite, rouvrez un terminal, et jetez un œil à la sortie de la bind -Pcommande, que vous pouvez lire dans un tampon Vim:

bind -P | vim -R -

Je ne suis pas sûr, mais je pense qu'il devrait afficher la plupart ou la totalité des readlineraccourcis clavier. Si vous recherchez le nom de la fonction readline liée à la C-tclé, dans le tampon Vim, vous feriez une recherche \\C-t. Et si vous cherchiez celui lié à M-c(touche méta / alt), vous rechercheriez \\ec( \esignifie la touche d'échappement et il semble M-cproduire les mêmes codes clés que escape + c).

Vous pouvez faire la même chose en zshregardant la sortie de la bindkeycommande. Mais cette fois, ^[représente la touche de modification meta / alt, tandis qu'un seul caractère caret ( ^) représente la touche de contrôle.


Actuellement, j'ai trouvé 4 raccourcis clavier exécutant des fonctions contenant le fzfmot - clé dans leur nom. Ils utilisent les séquences de touches C-i(identiques à Tab) C-r,, C-tet M-c. Ils sont liés aux fonctions suivantes:

C-i    fzf-completion
C-r    fzf-history-widget
C-t    fzf-file-widget
M-c    fzf-cd-widget

Sur mon système, à l'origine, readline(la bibliothèque utilisée par bashpour modifier la ligne de commande) a lié ces clés à ces fonctions:

C-i     complete
C-r     reverse-search-history
C-t     transpose-chars
M-c     capitalize-word

Et zle(l'éditeur de ligne utilisé par zsh), les a liés à:

C-i     expand-or-complete
C-r     history-incremental-search-backward
C-t     transpose-chars
M-c     capitalize-word
user9433424
la source
1
Un agplugin / outil distinct doit-il être installé?
ideasman42
@ ideasman42 Oui, désolé, j'ai oublié que la commande shell agétait également nécessaire. J'ai mis à jour la réponse.
user9433424
1
Il est probablement intéressant de noter que ces outils sont assez intrusifs, remplaçant vos configurations bash et zsh par défaut.
ideasman42
@ ideasman42 Vous avez raison, j'ai mis à jour la réponse pour mentionner ce problème.
user9433424