Как интерактивно искать / grep с VIM?

12

Есть ли способ настроить VIM для интерактивного поиска внутри каждого файла для всего проекта?

Под интерактивом я подразумеваю обновление каждого нажатия клавиши.

Что-то вроде Emacs counsel-git-grep , см. Пример демо .

ideasman42
источник
Я не использую это лично, поэтому я не уверен на 100%, но я думаю, ctrl-pили подобный плагин - то, что вы ищете. Обратите внимание, что это unite.vimтоже должно быть в состоянии сделать, но я бы не рекомендовал этого, потому что, на мой взгляд, это довольно тяжелый и создающий ошибки плагин.
statox
Есть ли ctrl-pспособ интерактивного поиска содержимого файла? Я использовал его только для интерактивного поиска файлов по их именам.
ideasman42
Я думаю, что это возможно, но, как я уже сказал, я не использую его, так что, возможно, я ошибаюсь
statox

Ответы:

14

Я не уверен, что это то, что вы ищете, но, возможно, вы могли бы попробовать fzf и fzf.vim .

Если вы используете vim-plug в качестве менеджера плагинов, все, что вам нужно сделать, чтобы установить их, это добавить следующие строки в ваш vimrc:

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

... где-то между строк:

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

и:

call plug#end()

Затем выполните :PlugInstall.


Среди различных команд и отображений, предоставляемых fzf.vim(чья единственная цель, по-видимому, заключается в установке отображений и команд, запрашивающих fzfнечеткий поиск по предопределенным источникам), есть команда :Ag.

Чтобы использовать его, вам нужно установить команду оболочки ag . В дистрибутивах на основе Debian это можно сделать с помощью следующей команды:

apt-get install silversearcher-ag

Проект на github объясняет, как установить его на MacOS:

brew install the_silver_searcher

:Agявляется оберткой вокруг $ agи позволяет нечетко искать шаблон в файлах текущего каталога (тот, который отображается при вводе :pwd). Матчи обновляются после каждого нажатия клавиши.

Вы можете:

  • цикл вперед и назад через матчи с C-nиC-p
  • выберите текущий матч и перейдите к следующему / предыдущему с помощью Tab/S-Tab
  • выберите или отмените выбор всех совпадений с помощью M-aилиM-d

Если вы выберете одно или несколько совпадений, после нажатия Enter они будут заполнены списком быстрых исправлений. Оттуда вы сможете перемещаться по ним с помощью команд / отображений Vim по умолчанию, таких как :cnextи :cprevious.

введите описание изображения здесь

Если вы хотите добавить префикс ко всем установленным командам fzf.vimи избежать переопределения существующих команд, вы можете добавить это в vimrc:

let g:fzf_command_prefix = 'your_prefix'

Я использую Fzfв качестве префикса, поэтому я не печатал, :Agно :FzfAg.


Если вы предпочитаете использовать git grepвместо ag, кажется, вы можете установить вокруг него свою собственную оболочку, :GGrepнапример:

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

Это объясняется в :h fzf-vim-customization.

Кроме того , если fzfоткрывает панель в tmux, и вы предпочли бы это занимает весь экран вместо этого, вы можете добавить челку для всех команд ( :Ag!, :GGrep!, ...).


Как вы сказали в своем последнем комментарии , по умолчанию fzfизменяется конфигурация вашей оболочки. Например, если вы используете bash, он добавит следующую строку в ваш ~/.bashrc:

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

Это будет источником файла ~/.fzf.bash. Последний содержит некоторый код:

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

Этот код добавляет путь к переменной окружения $PATH: /home/user/.fzf/bin; это папка, содержащая fzfпрограмму.

Он также содержит 2 других файла:

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

Первый, похоже, определяет функции завершения, а второй устанавливает привязки клавиш.

К сожалению, привязки клавиш могут переопределять readlineфункции по умолчанию .
Например, fzfсвязывает функцию fzf-file-widgetс C-t. Этот ключ обычно используется readline для выполнения transpose-charsфункции.

Если вы не хотите этого, одним из возможных решений было бы восстановить привязки клавиш внутри вашей ~/.bashrc, после того, как fzfон выбрал ее конфигурацию. Например, если вы хотите C-tсохранить его старое поведение, то есть транспонировать 2 символа вокруг курсора и привязать fzf-file-widgetк другой клавише, скажем C-x C-t, вы можете добавить эти строки в конце ~/.bashrc:

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

То же самое относится и к zshоболочке, но синтаксис для установки привязки ключей немного отличается:

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

Если одна из привязок ключа оболочки, к которой вы привыкли, была переопределена fzf, вы хотите восстановить ее, но не знаете, какое именно имя функции было выполнено, вы можете попробовать следующее.

Сначала, внутри ~/.bashrc, временно закомментируйте строку, которая является источником fzfконфигурации. Затем снова откройте терминал и посмотрите на вывод bind -Pкоманды, которую вы можете прочитать в буфере Vim:

bind -P | vim -R -

Я не уверен, но я думаю, что он должен отображать большинство или все readlineпривязки клавиш. Если вы ищете имя функции readline, связанной с C-tклавишей, в буфере Vim вы будете искать \\C-t. И если вы искали привязанный к M-c(мета / альтернативный ключ), вы бы искали \\ec( \eобозначает escape-ключ, и кажется, что он M-cпроизводит те же коды клавиш, что и escape + c).

Вы можете сделать то же самое zsh, посмотрев на вывод bindkeyкоманды. Но на этот раз это ^[клавиша-модификатор meta / alt, в то время как одиночный ^символ caret ( ) обозначает клавишу управления.


В настоящее время я нашел 4 привязки клавиш, выполняющие функции, содержащие fzfключевое слово в их имени. Они используют последовательности клавиш C-i(так же, как Tab) C-r, C-tи M-c. Они связаны со следующими функциями:

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

Первоначально в моей системе readline(библиотека, используемая bashдля редактирования командной строки) связывала эти ключи с этими функциями:

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

И zle(редактор строк, используемый zsh) связал их с:

C-i     expand-or-complete
C-r     history-incremental-search-backward
C-t     transpose-chars
M-c     capitalize-word
user9433424
источник
1
Это agотдельный плагин / инструмент, который нужно установить?
ideasman42
@ ideasman42 Да, извините, я забыл, что команда оболочки agтакже была необходима. Я обновил ответ.
user9433424
1
Вероятно, стоит отметить, что эти инструменты довольно навязчивы, заменяя ваши конфигурации bash и zsh по умолчанию.
ideasman42
@ ideasman42 Вы правы, я обновил ответ, чтобы упомянуть эту проблему.
user9433424