Поиск и замена с использованием списка быстрых исправлений в Vim - PullRequest
37 голосов
/ 16 апреля 2011

До сих пор я всегда использовал EasyGrep для замены текста в нескольких файлах.К сожалению, это довольно медленно, когда проект становится больше.Одна вещь, которая кажется удивительно быстрой, это Ggrep из fugitive.vim, который ищет только мои файлы с контролем версий.Все результаты также сохраняются в списке быстрых исправлений.

Как я могу использовать результаты Ggrep для простой замены всех найденных файлов?Можно ли как-то использовать %s/foo/bar/cg для всех файлов в списке быстрых исправлений или есть способы получше?

Ответы [ 6 ]

65 голосов
/ 16 апреля 2011

Обновление: У Vim теперь есть cdo, см. Ответ Сида .

Оригинальный ответ:

Vimимеет bufdo, windo, tabdo и argdo, что позволяет выполнять одну и ту же команду во всехоткрыть буферы, окна или файлы в списке аргументов.Нам действительно нужно что-то вроде quickfixdo, которое будет вызывать команду для каждого файла в списке быстрых исправлений.К сожалению, этой функциональности не хватает в Vim, но вот решение на Al , которое обеспечивает решение домашнего проката.Используя это, можно будет выполнить:

:QFDo %s/foo/bar/gc

И это приведет к подстановке foo / bar для всех файлов в списке быстрых исправлений.

bufdo, windoКоманды, tabdo и argdo имеют некоторое общее поведение.Например, если текущий файл нельзя отменить, все эти команды не будут выполнены.Я не уверен, что указанная выше команда QFDo соответствует тем же соглашениям.

Я адаптировал решение Ала для создания команды с именем Qargs.Выполнение этой команды заполняет список аргументов всеми файлами, перечисленными в списке быстрых исправлений:

command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames()
function! QuickfixFilenames()
  " Building a hash ensures we get each buffer only once
  let buffer_numbers = {}
  for quickfix_item in getqflist()
    let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
  endfor
  return join(values(buffer_numbers))
endfunction

Используя это, вы можете выполнить следующие шаги для поиска и замены в масштабах всего проекта:

:Ggrep findme
:Qargs
:argdo %s/findme/replacement/gc
:argdo update

Редактировать: (с советами от Питера Ринкера)

Или вы можете объединить последние 3 команды вместе в одной строке:

:Ggrep findme
:Qargs | argdo %s/findme/replacement/gc | update
31 голосов
/ 25 июля 2016

cdo команда была добавлена!После того, как вы grep, вы можете использовать cdo для выполнения данной команды для каждого термина в вашем списке быстрых исправлений:

cdo %s/<search term>/<replace term>/cg

(Взгляните на этот git commit и это обсуждение в группе разработчиков gim для получения дополнительной информации о cdo и мотивах ее добавления.)

14 голосов
/ 13 января 2013

Ответ Нельстрома весьма исчерпывающий и отражает его блестящий вклад в vimdom. Это также выходит за рамки того, что здесь строго необходимо; шаг быстрого исправления может быть пропущен в пользу заполнения аргументов результатом команды оболочки:

:args `git grep -l findme`
:argdo %s/findme/replacement/gc
:argdo update

должно быть все, что вам нужно.

Редактировать: как отмечает Домон,: сначала нужно установить скрытый, если он еще не установлен!

3 голосов
/ 04 апреля 2014

Используя quickfix-refleor.vim , вы можете редактировать результаты поиска в окне быстрого исправления.Команда write сохранит изменения в ваших файлах.

:copen
:%s/foo/bar/cg
:write
3 голосов
/ 16 апреля 2011

Внешний grep

(использует grepprg, grepformat, как в makeprg / errorformat; если grepprg == 'internal', это идентично внутреннему grep)

:grep fopen *.c
:copen
:cnext

Внутренний grep

:vimgrep /\<myVimregexp\>/ **/*.c
:copen
:cnext

и т.д.

Список местоположений внутреннего grep

:lvimgrep /\<myVimregexp\>/ **/*.c
:lopen
:lnext

и т.д.

Бонус: выполнение внешнего grep для загруженных буферов:

:silent bufdo grepadd fstream %
:copen
:cnext

и т.д.

Внешний для всех аргументов:

:silent argdo grepadd fstream %
:copen
:cnext
1 голос
/ 25 марта 2015

Есть патч для добавления команды cdo (Quickfix do) в vim, но он еще не был извлечен (по состоянию на 2015-03-25):

https://groups.google.com/forum/#!topic/vim_dev/dfyt-G6SMec

Возможно, вы захотите патч vim самостоятельно, чтобы получить этот патч:

brew install hg # install mercurial, e.g. with homebrew
hg clone https://vim.googlecode.com/hg/ vim
cd vim
# copy/download patch to . folder
patch -b -p1 < cdo.diff
./configure
make && make install
...