Como pesquisar / grep interativamente com o VIM?

12

Existe alguma maneira de configurar o VIM para pesquisar interativamente em cada arquivo um projeto inteiro?

Por interativo , quero dizer atualizar cada pressionamento de tecla.

Algo como o Emacs advis-git-grep , veja: exemplo de demonstração .

ideasman42
fonte
Eu não o uso pessoalmente, então não tenho 100% de certeza, mas acho que ctrl-pum plugin semelhante é o que você está procurando. Note que unite.vimtambém deve ser capaz de fazer isso, mas eu não o recomendaria, porque, na minha opinião , é um plugin bastante pesado e que cria bugs.
statox
Existe ctrl-puma maneira de pesquisar interativamente o conteúdo do arquivo? Eu só o usei para procurar interativamente arquivos com base em seus nomes.
usar o seguinte código
Eu acho que é possível, mas como eu disse, não o uso, então talvez eu esteja errado #
statox

Respostas:

14

Não tenho certeza se é isso que você está procurando, mas talvez você possa experimentar o fzf e o fzf.vim .

Se você usa o vim-plug como um gerenciador de plugins, tudo o que você precisa fazer para instalá-los é adicionar estas linhas no seu vimrc:

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

... algures entre as linhas:

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

e:

call plug#end()

Então execute :PlugInstall.


Entre os vários comandos e mapeamentos fornecidos por fzf.vim(cuja única finalidade parece ser a instalação de mapeamentos e comandos que solicitam fzfa pesquisa difusa por fontes predefinidas), existe o comando :Ag.

Para poder usá-lo, você precisa instalar o comando shell ag . Nas distribuições baseadas no debian, isso pode ser feito com o seguinte comando:

apt-get install silversearcher-ag

O projeto no github explica como instalá-lo no MacOS:

brew install the_silver_searcher

:Agé um invólucro $ age permite que você pesquise um padrão nos arquivos do diretório atual (aquele exibido quando você digita :pwd). As correspondências são atualizadas após cada pressionamento de tecla.

Você pode:

  • avançar e retroceder nas partidas com C-neC-p
  • selecione a correspondência atual e vá para a próxima / anterior com Tab/S-Tab
  • marque ou desmarque todas as correspondências com M-aouM-d

Se você selecionar uma ou várias correspondências, depois de pressionar Enter, elas preencherão a lista de correções rápidas. A partir daí, você poderá navegar por eles com comandos / mapeamentos padrão do Vim, como :cnexte :cprevious.

insira a descrição da imagem aqui

Se você deseja adicionar um prefixo a todos os comandos instalados por fzf.vime evitar a substituição de comandos existentes, você pode adicioná-lo em vimrc:

let g:fzf_command_prefix = 'your_prefix'

Eu uso Fzfcomo prefixo, é por isso que não digitei :Agmas :FzfAg.


Se você preferir usar em git grepvez de ag, parece que você pode instalar seu próprio wrapper personalizado em torno dele, da :GGrepseguinte maneira:

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

É explicado em :h fzf-vim-customization.

Além disso, se fzfabre um painel no tmux, e você preferiria que toma toda a tela em vez disso, você pode acrescentar um estrondo a todos os comandos ( :Ag!, :GGrep!...).


Como você disse em seu último comentário , por padrão, fzfaltera a configuração do seu shell. Por exemplo, se você usar bash, ele adicionará a seguinte linha no seu ~/.bashrc:

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

Isso irá originar o arquivo ~/.fzf.bash. Este último contém algum código:

# 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"

Este código adiciona um caminho para a variável de ambiente $PATH: /home/user/.fzf/bin; qual é a pasta que contém o fzfprograma.

Ele também origina 2 outros arquivos:

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

O primeiro parece definir funções de conclusão, enquanto o segundo instala ligações de teclas.

Infelizmente, as combinações de teclas podem substituir as readlinefunções padrão .
Por exemplo, fzfvincula a função fzf-file-widgeta C-t. Essa tecla é geralmente usada pelo readline para executar a transpose-charsfunção.

Se você não quiser isso, uma solução possível seria restaurar as ligações de teclas dentro do seu ~/.bashrc, depois de fzfter originado sua configuração. Por exemplo, se você deseja C-tmanter seu comportamento antigo, é a transposição dos 2 caracteres ao redor do cursor e a ligação fzf-file-widgeta outra chave, digamos C-x C-t, você pode adicionar essas linhas no final de ~/.bashrc:

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

O mesmo se aplica ao zshshell, mas a sintaxe para instalar uma ligação de chave é um pouco diferente:

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

Se uma das ligações da tecla shell a que você estava acostumada foi substituída fzf, você deseja restaurá-la, mas não sabe qual é o nome exato da função que foi executada, tente o seguinte.

Primeiro, dentro do seu ~/.bashrc, comente temporariamente a linha que origina a fzfconfiguração. Em seguida, reabra um terminal e dê uma olhada na saída do bind -Pcomando, que você pode ler em um buffer do Vim:

bind -P | vim -R -

Não tenho certeza, mas acho que deve exibir a maioria ou todas as readlinecombinações de teclas. Se você está procurando o nome da função readline vinculada à C-tchave, no buffer do Vim, você deve pesquisar \\C-t. E se você estivesse procurando pela pessoa vinculada a M-c(tecla meta / alt), pesquisaria \\ec( \esignifica a tecla escape e parece M-cproduzir os mesmos códigos de chave escape + c).

Você pode fazer a mesma coisa zshobservando a saída do bindkeycomando. Mas desta vez, ^[significa a tecla modificadora meta / alt, enquanto um único ^caractere de sinal de intercalação ( ) representa a tecla de controle.


Atualmente, encontrei 4 ligações de teclas executando funções que continham a fzfpalavra - chave em seu nome. Eles usam as seqüências de teclas C-i(iguais a Tab) C-r,, C-te M-c. Eles estão vinculados às seguintes funções:

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

No meu sistema, originalmente readline(a biblioteca usada bashpara editar a linha de comando) vinculava essas chaves a estas funções:

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

E zle(o editor de linha usado por zsh), vincule-os a:

C-i     expand-or-complete
C-r     history-incremental-search-backward
C-t     transpose-chars
M-c     capitalize-word
user9433424
fonte
1
É agum plugin / ferramenta separado que precisa ser instalado?
usar o seguinte código
@ ideasman42 Sim, desculpe por isso, esqueci que o comando shell agtambém era necessário. Eu atualizei a resposta.
usar o seguinte comando
1
Provavelmente vale a pena notar que essas ferramentas são bastante intrusivas, substituindo as configurações do bash e do zsh por padrão.
ideasman42
@ ideasman42 Você está certo, atualizei a resposta para mencionar esse problema.
user9433424