Я бы хотел оптимизировать рабочий процесс поиска и замены в Vim. Это то, чем я занимаюсь часто, и я уверен, что большинство из вас тоже. Обычно что-то в этом роде - копирование блока и изменение имени переменной в нескольких местах. Я знаю, я знаю, что это, вероятно, вызывает ваш рефлекс «почему вы копируете и вставляете код», но давайте не будем идти по этому пути ... Есть много действительных вариантов использования :)
Я хорошо знаю команды поиска и замены: :s
или :%s
мне они не нравятся. Это заставляет меня печатать полное имя переменной, которую я ищу, и то, на что я ее изменяю. Может быть, есть лучший способ исправить количество набрав с :%s
? Я часто использую длинные описательные имена переменных, так что это действительно нарушает условия сделки. Мне также не нравится, как ввод имени переменной с нуля является склонным к опечаткам и может потребовать времени и умственных способностей для поиска опечаток. Я предпочитаю набирать его один раз, а затем копировать и вставлять, чтобы просто избежать этого, если это возможно.
Мой текущий рабочий процесс использует некоторую комбинацию движения / yank / select / search / put для перемещения по файлу и замены одного за другим. Это не очень хорошо, но имеет преимущество в том, что избегает ввода полных имен переменных. Возможно, мне просто нужно набрать первые несколько букв с помощью /
или использовать другую команду движения (например fx
), в зависимости от того, что вокруг, а затем нажать, ve
чтобы выбрать все слово. Я также не против, что я должен повторять для каждого случая. Я никогда не делаю полную замену без подтверждения каждого изменения. Но было бы намного предпочтительнее, если бы я мог повторить действие замены одним нажатием клавиши (что я не могу сделать с этим методом). каждая замена, как правило , что - то вроде n
то ve
тогда p
(или даже хуже "0p
)
Есть ли более быстрый способ?
источник
.
повторяет последний «командный блок» (не уверен в точном термине. Например: Move + Action + Text. Например:cwtoto<Esc>
(переход от курсора к концу слова с помощью «toto»),c/foo<enter>bar<Esc>
(переход от курсора до непосредственно перед » foo ", и заменить на" bar "). Затем вы можете переместить (с помощью курсора, hjkl или числа + hjkl (делает это n раз), G (перейти в конец файла), / что-то (перейти непосредственно перед" что-то ") и т. д.), а затем нажмите,.
чтобы повторить тот же" командный блок "n
ve
"0p
. К сожалению, это не может быть воспроизведено только с.
n ce ctrl-r 0 <esc> n.n.n.n.n.n.
Ответы:
У меня фактически есть рабочий процесс, довольно похожий на ваш (копирование и вставка блоков, которые похожи, затем использование
:s
для изменения имен переменных), особенно когда я пишу много похожих строк, за исключением того, какую переменную они используют. Но есть пара вещей, которые я делаю, которые вы можете найти полезными.Общие вещи
Первое, что поможет вам, это понять, что
:s//foo/g
заполнит любой поисковый запрос, который вы использовали последним, и заменит его на foo . Одно это может сэкономить много времени, но когда вы объединяете его с помощью команды звездочки (ищите слово под текущим курсором), это экономит массу времени. Например, чтобы изменить всеfoo
наspam
вместоЧто требует от вас ввода foo и spam (которые могут быть длинными переменными), вы можете просто перейти к foo и выполнить:
Таким образом, вы можете быстро получить имя переменной, которую вы меняете, выполнив ее поиск, тогда вам не нужно будет ее печатать. Это также будет хорошо работать с вашим текущим рабочим процессом использования
n
много. Это также полезноhlsearch
, потому что тогда вы можете визуально определить, где находятся переменные, которые вы заменяете.(примечание: команда звездочки добавит границы слов, то есть
\<
и\>
вокруг слова под курсором. Если вы не хотите этого, используйтеg*
вместо этого.)Вы можете использовать,
@:
чтобы повторить последнюю команду замены. Это хорошо, если вы хотите выполнить:s
команду на множестве строк, но не все из них, поэтому:%s
не будут работать. Другим вариантом является флаг подтверждения, то есть:%s///gc
. Это позволит вам вводитьy
илиn
при каждом появлении решать, хотите ли вы заменить его или нет.Как указал Дести , вы также можете &выполнить последнюю команду замещения, но учтите, что это не сохранит ваши флаги (например,
global
илиconfirm
). Хорошо это или плохо, зависит от вашего личного мнения. Если вы хотели бы использовать это, но сохранить флаги, вы можете сделатьЕсли вы хотите изменить каждое вхождение в блоке, но не каждое совпадение в файле, вы всегда можете использовать визуальный выбор блока, который заполнит
к вашей замене, которая ограничивает его линиями, которые вы выбрали. В сочетании со звездочкой я считаю это чрезвычайно полезным. Кроме того, если вы делаете несколько команд замещающих на том же блоке строк, вы можете использовать , gvчтобы повторно одни и те же линии , чтобы сделать еще одну команду. (будь то
:substitute
или нормальная команда)Если вы делаете другую команду замены, вам не нужно повторно выбирать те же строки, потому что
:'<,'>
они все равно будут работать на тех же строках. Однако удобнее набиратьскорее, чем
Плагины / Отображения, которые мне нравятся
У меня есть следующее отображение в моем,
.vimrc
которое расширяет подход звездочки, так что мне нужно только ввести новое желаемое имя:Чтобы использовать это, просто наведите курсор на слово, которое вы хотите изменить, и наберите,
<leader>rNewVarName<cr>
и все готово. Обратите внимание, что это заменит все совпадения, не давая вам возможности подтвердить их, поэтому вам это может не понравиться. Конечно, вы можете просто изменить его наЧтобы разрешить опцию подтверждения.
редактировать : следуя как ответу Мессы, так и комментарию rcorre , вы также можете написать это как
Который имеет то преимущество, что ваш неназванный регистр остается неизменным.
Если вы переименовываете группы одинаковых переменных одновременно, например, меняете
в
это может быть боль, чтобы заменить их всех по отдельности. Здесь пригодится tpope / vim-abolish . Вы можете заменить все это одной командой:
и он заботится о капитализации для вас.
Это должно вам очень помочь, но дайте мне знать, если что-то в этих подходах вам не нравится или вам не хватает. Я рад поговорить о других подходах. :)
Рекомендуемое чтение:
:h s_c
:h *
:h g*
:h @:
:h /\<
:h &
источник
<leader>rc
(илиcr
) добавить это/c
в конце. Кроме того, яset gdefault
установил, потому что я почти никогда не хочу заменять один единственный результат, так что это будет простоyiw:%s/\<<C-r>"\>//<left><left>
ctrl+r-ctrl+w
отображение (как предложено @Mass), оно должно работать так же, но не будет портиться с вашим регистром янки (что может или не может быть желательно).
для выполнения дальнейших замен.c_CTRL-R
Семейство карт может улучшить свой рабочий процесс совсем немного:Вам не нужно вводить имена переменных при использовании
:s/
, просто используйтеCTRL-R
CTRL-W
для вставки слова под курсором в командную строку (предостережение: это не экранирует специальные символы, как это*
делает).Сделав небольшое изменение с помощью
ce
, вы можете искать старое слово с помощью/
CTRL-R
-
. Затем используйте,.
чтобы повторить изменение.Если вам нужно внести изменения в шаблон поиска
CTRL-R
/
, поместите существующий поиск в командную строку.Наконец, вы можете поместить содержимое любого регистра, используя
CTRL-R
{register}
источник
Ctrl-R
/
? Я использую это довольно часто в:s
командах, если я хочу использовать поисковый термин, который почти, но не совсем совпадает с предыдущим.Есть еще пара методов, которые (к моему удивлению!) Еще не были упомянуты.
Использование
gn
командыgnработает как nкоманда, за исключением того, что в дополнение к переходу на совпадение, он входит в визуальный режим с выбранным совпадением.
Таким образом, чтобы изменить слово (или что-либо, что вы можете сопоставить с регулярным выражением!), Сначала найдите его 1 , а затем нажмите, а затем cgnтекст, которым вы хотите заменить совпадение, и Escвернитесь в обычный режим.
(Вы упоминаете, что иногда текст замены, который вы хотите использовать, сохраняется в
"0
регистре янки - обратите внимание, что вы можете быстро ввести его, не вводя его повторно, нажав Ctrl+R0в режиме вставки.)Затем вы можете перейти к следующему совпадению и повторить изменение одним .нажатием клавиши!
Если есть места, где вы не хотите производить замену, просто нажмите, unчтобы отменить изменения и перейти к следующему совпадению.
1: Быстро, используя другие предложения на этой странице, такие как *, Ctrl+RCtrl+Wи т. Д. См. Также комментарий Питера Ринкера для получения дополнительных предложений о том, как изначально заполнить ваш поиск.
Использование режима выбора
(Я это из узнал romainl «s запись на VIM subreddit . Я не знаю , придумал ли он это сам или просто передать его.)
Режим выбора немного похож на визуальный режим, за исключением того, что если вы начинаете печатать, выделенный текст немедленно заменяется тем, что вы печатаете (например, как выбор работает в большинстве других редакторов).
Таким образом, вы можете использовать это трио сопоставлений для очень быстрого поиска / замены, который вы можете изменить в середине файла, если необходимо:
Отображение нормального режима : входит в режим выбора со словом, ближайшим к выбранному курсору.
Затем вы можете ввести замену для выбранного слова и ( без нажатия Esc) использовать:
Сопоставление режима вставки : переход к следующему совпадению и переход в режим выбора.
Затем вы можете либо ввести новую замену, либо нажать, .чтобы использовать:
Выбор режима отображения : повторно вводит последний вставленный текст - по существу, повторяет последнюю вставку.
источник
gn
метод в конце моего ответа vi.stackexchange.com/a/13696/488 вчера за то, что он стоит! Ваш ответ имеет гораздо более приятное форматирование.gn
один раз), и это был специфический метод (а не простоgn
команда), который, как я был удивлен, еще не упоминался.gn
. Дает вам больше вариантов поиска. Визуальное картирование звезд бедняковxnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>
. Связанный эпизод Vimcasts: Работа над поиском совпадений с использованием gnПлагин https://github.com/terryma/vim-multiple-cursors решает эту проблему по большей части.
Мой рабочий процесс обычно выглядит следующим образом:
ctrl-n
пока все не выбрано.c
и начните вводить замену.Здесь удобно то, что вы также можете выполнять более сложные операции, чем просто поиск-замена, хотя я считаю, что если вы зайдете слишком далеко, плагин начнет показывать некоторые глюки.
источник
Еще один способ сделать то, что еще не было упомянуто: вы можете использовать окно командной строки (открывается
q:
в обычном режиме - см.:help q:
Дополнительную информацию), в котором у вас есть полный доступ к функциям автозаполнения Vim (i_CTRL-N
/i_CTRL-P
и различнымi_CTRL-X
последовательностям). быть среди них).В окне командной строки вы также можете использовать команды обычного режима для редактирования командной строки, что, например, означает, что вы можете восстановить и вставить части предыдущих команд в свою историю командной строки.
Обратите внимание, что ваш курсор будет перемещен в окно командной строки при его использовании, а это означает, что
CTRL-R CTRL-W
аналогичные методы, которые включают вставку текста под курсором, не будут работать там, в отличие от обычной командной строки.источник
:substitute
команды, нажав<ctrl-f>
Решение этой проблемы несколько другое для меня:
Допустим, у вас есть 6 одинаковых строк, и вы хотите заменить «яблоко» в середине двух:
Что я делаю это:
v
чтобы войти в визуальный режим2j
:s/<C-R><C-W>/
который использует визуальный выбор в качестве диапазона:s
, а затем вставляет слово под курсором<C-F>
что переводит вас в режим, в котором вы можете редактировать свою команду, как если бы она была буфером. Таким образом, вы можете использовать любое завершение или плагины, которые вы хотите выбрать слово для замены, и все готово.Все в одной строке, поток для этого будет,
/apples<CR>2nv/apples<CR>nn:s/<C-R><C-W/oranges<CR>
но это выглядит хуже, чем есть.В вашем случае, вы можете присоединить
/c
к:s
команде , чтобы пропустить те , которые вы не хотите, если диапазон содержит несколько вы хотите пропустить::s/<C-R><C-W/orange/c
.В качестве альтернативы (и, возможно, более просто), вы можете найти все слово, которое хотите заменить,
c
изменить его, затемgn
и.
повторить поиск и применить то же изменение снова. Было бы похоже/\<apple\><CR>viwcorange<ESC>gn.gn.gn..ngn.
повторить это на трех, затем пропустить экземпляр, а затем повторить в последний раз.источник
vim -Nu NONE
). Просто гудит, когда я нажимаю первый.
. Есть идеи, почему это так? В любом случае было бы проще использоватьciw
вместоviw
иn
вместо того,gn
чтобы вносить изменения таким образом.Это не совсем связано с вопросом, но все же должно помочь выбрать слово для замены.
Инкрементальный поиск (
set incsearch
) позволяет вам ввести префикс слова, которое вам нужно найти, и vim автоматически перейдет к первому вхождению префикса, когда вы будете вводить все больше и больше. Поиск будет подтвержден, если вы нажмете Enter и откажетесь от Esc (в последнем случае курсор вернется туда, где он был до начала поиска).Тем не менее, добавочный поиск предоставляет еще одну полезную функцию. Когда вы уже набрали префикс слова и курсор находится в правильной позиции, нажмите,
<C-L>
чтобы добавить символы из слова под курсором в строку поиска. Это позволяет вводить замененную строку практически без нажатия клавиш.Так что , если я хочу заменить
someOddVariableName
сevenOdderVariableName
, я/someOddV
и получите вхождениеsomeOddVariableName
;<C-L>
пока полностью неsomeOddVariableName
появится в строке поиска;:%s//evenOdderVariableName/g
или какую бы команду вы ни заменили; Вы можете следовать другим ответам здесь.источник
Вы можете сначала поместить имя переменной в буфер (
yw
для копирования слова), а затем скопировать и вставить ее:%s
, нажав<C-r>"
.источник
Если вы хотите заменить переменную в новом (вставленном) блоке, у меня есть два предложения:
Автоматическая замена
Перейти к первой строке нового блока, нажать
ma
. Это отмечает место и называет егоa
.Перейти к последней строке нового блока, нажмите
mb
. Теперь у вас есть два названных местоположения.Теперь замените между этими двумя линиями, например , так:
:'a,'bs/oldVarName/newVarName/g
.То есть объем замены находится между вашими двумя отметками.
Ручной способ
Перейти к первой строке нового блока.
Используйте,
/oldVarName
чтобы найти первый экземплярoldVarName
.Измените это так:,
cwnewVarName<Esc>
который изменит слово наnewVarName
и ударит escape.Используйте
n
для перехода к следующему экземпляруoldVarName
.Используйте,
.
чтобы повторить последнее изменение (т.е. повторяет этоcw
).источник
Многие другие ответы здесь уже охватывают встроенные способы улучшить рабочий процесс поиска и замены, но я хотел бы упомянуть abolish.vim , плагин от Tim Pope. Это делает замены там, где вы хотите охватить более широкий диапазон падежей, как правило, из-за различий в падеже или потому, что вам нужно иметь дело как с единственной, так и с множественной формой слова.
:S/child{,ren}/adult{,s}/g
правильно конвертируетchild
вadult
,Children
вAdults
иCHILD
вADULT
.Если вы имеете дело со словами в верблюжьих словах, вам нужно указать заглавные буквы там, где они вам нужны, в исходных и заменяющих словах.
%:S/wordWrap/textBreak/g
правильно обрабатывает какwordWrap
иwordwrap
.источник
Как уже отмечали другие, если вы поместите курсор поверх своего слова, вы можете использовать семейство команд Ctrl + r, наиболее подходящим для использования является Ctrl + r Ctrl + w.
Этот метод, однако, работает только для вставки одного слова (того, которое находится чуть ниже курсора), но что, если в буфере есть несколько частей текста, которые мы хотим использовать? Как вы не можете переместить курсор в командной строке. Лучший способ сделать это - скопировать части текста, которые вам понадобятся, в разные регистры, что можно сделать, добавив префикс "{reg_letter} (цитата и письмо из регистра) к оператору копирования. Таким образом, будет возможно вставьте различные слова в командную строку позже с помощью Ctrl + r {reg_letter}. Это немного неловко, но работает.
Но, возвращаясь к предыдущей идее, было бы здорово, если бы мы переместили позицию курсора над буфером во время написания паттерна. Таким образом, мы могли бы «выбирать» текст из разных позиций с помощью Ctrl + r Ctrl + w, поэтому я создал плагин, который делает именно это: EXtend.vim Плагин также имеет много других функций для выполнения операций замещения.
источник