Заключение в круглые скобки с помощью Vim

Есть ли способ заключить текст в круглые скобки (или фигурные скобки) в vim?

Другими словами, как бы вы это сделали?

Исходная строка:

It is sunny outside.

Конечная строка:

It is (sunny) outside.

Забавно, я просто нажал :w, чтобы отправить этот вопрос.

Счастливого настроения, SOCommunity!


person eqb    schedule 09.11.2011    source источник
comment
Кажется, что макрос может легко выполнить эту работу, но я не осмеливаюсь прописать какой-то конкретный - я еще довольно зеленый в VIM. Но что-то вроде «переместиться в начало слова, вставить левую скобку, перейти в конец слова, вставить правую скобку» звучит как макрос, который будет работать в большинстве случаев...   -  person Triptych    schedule 10.11.2011
comment
@Triptych - Как вы и предложили, только сопоставление вместо макроса. Смотрите мой ответ.   -  person Rook    schedule 10.11.2011


Ответы (12)


Surround.vim должен помочь. Если вы хотите повторить это с помощью '.', см. здесь.

person mwilson    schedule 09.11.2011

Одним словом, я использовал:

bcw()<Esc>P

То есть перейдите к началу слова, вырежьте слово и перейдите в режим вставки, введите скобки, а затем выйдите из режима вставки и вставьте слово обратно.

Имейте в виду, что это перезапишет ваш регистр янки.

Вы, конечно, можете заменить bcw любыми движениями и типами выбора, которые вам нужны, например

5cc{<Enter>}<Esc>P
person Ian Hatch    schedule 11.07.2014
comment
Я ненавижу, когда мои янки перезаписываются. - person d1str0; 25.02.2016
comment
Плагин не нужен. Здорово. Честно говоря, с Surround.vim вам нужно нажимать примерно такое же количество клавиш, так зачем использовать плагин? - person hamid; 26.02.2018
comment
Сильной стороной vim является его язык управления курсором! Спасибо! Это легко записать в скрипт и сделать макросом. qbcw()<Esc>Pq, затем @q, чтобы быстро повторить слова. - person Thomson Comer; 27.02.2018
comment
@ d1str0 вы все еще можете найти свой yank в регистре "0 - person Bananach; 26.06.2018
comment
тангенциальный, но янки действительно должны были быть объединены в стек, как и отмена. - person hraban; 21.03.2019
comment
Чтобы сделать это немного быстрее, для отдельных слов я обычно делаю ciw () <C-r> ". Control r вставляет последнее добавленное в регистр, поэтому я просто удостоверяюсь, что курсор находится в круглых скобках (большинство IDE и редакторов помещают туда автоматически, поэтому это происходит довольно быстро. ciw, очевидно, можно изменить на визуальное выделение, а остальную часть команды то же самое. - person joshpetit; 15.09.2020

Вот примеры использования surround.vim. В обычном режиме vim поместите курсор на нужное слово (в данном случае солнечное) и введите:

ysiw

Затем введите )

So:

начальная строка:

It is sunny outside.

Конечная строка:

It is (sunny) outside.

Дополнительный пробел. Используйте открывающую скобку или квадратную скобку, например ysiw(, чтобы окружить скобками и пробелом между скобкой и началом + концом слова)

Проще в визуальном режиме Войдите в визуальный режим, нажав v. Теперь, если вы наберете S(, слово будет окружено пробелами. Однако, если вы используете закрывающую ) вместо S), она не будет окружена пробелами.

Это относится ко всем окружениям пар скобок, <> [] {} (), а не только к (). Поведение S< таково, что он ожидает включения тега, поэтому только S> может окружать как <>.

Подробнее:

Введите ysiw, а затем }, чтобы сделать то же самое для завитков.

Сюда же можно добавить еще несколько примеров:

  • введите cs(', чтобы [c]изменить [s]окружение с ( на '

  • cs'( для перехода от ' окружения к ()

  • ds(. на [d]удалить ( [s]окружение полностью

Даже больше:

И почему бы не процитировать остальную часть страницы Tpope, чтобы мы не переходили по ссылке?

// начало цитаты:

Проще всего объяснить на примерах.

Нажмите cs"' внутри

"Привет мир!" изменить его на

'Hello world!'

--

Теперь нажмите cs'<q>, чтобы изменить его на

<q>Hello world!</q>

--

Чтобы пройти полный круг, нажмите cst", чтобы получить

"Hello world!"

--

Чтобы полностью удалить разделители, нажмите ds".

Hello world!

--

Теперь, когда курсор находится на «Hello», нажмите ysiw] (iw — текстовый объект).

[Hello] world!

Давайте сделаем эти фигурные скобки и добавим немного пробела (используйте } вместо { для отсутствия пробела): cs]{

{ Hello } world!

--

Теперь заключите всю строку в круглые скобки с помощью yssb или yss).

({ Hello } world!)

--

Вернуться к исходному тексту: ds{ds)

Hello world!

--

Подчеркните привет: ysiw<em>

<em>Hello</em> world!

--

Наконец, давайте попробуем визуальный режим. Нажмите заглавную V (для линейного визуального режима), а затем S<p class="important">.

<p class="important">
  <em>Hello</em> world!
</p>

Этот плагин очень мощный для редактирования HTML и XML, ниши, которая в настоящее время кажется недостаточно заполненной в мире Vim. (В отличие от вставки HTML/XML, для которой доступно множество плагинов). Добавлять, изменять и удалять пары тегов одновременно очень просто.

Команда . будет работать с ds, cs и yss, если вы установите repeat.vim.

person Danny    schedule 28.08.2014
comment
зачем нам y в ysiw? - person Jwan622; 08.07.2020
comment
@ Jwan622 Возможно, просто для того, чтобы избежать конфликтов с клавишей s в обычном режиме. Если бы это было siw, символ под курсором был бы заменен на iw, и мы остались бы в режиме вставки. Я думаю. Я не пробовал. - person byxor; 02.06.2021

Вы можете определить простое сопоставление для такого рода вещей. Это должно сделать это. В обычном режиме введите z, чтобы заключить слово в круглые скобки.

:nnoremap <leader>z viw<esc>a)<esc>hbi(<esc>lel
person Rook    schedule 09.11.2011
comment
Потрясающий. Простое нажатие 2 кнопок лидер + z. это мой любимый ответ - person Darren Haynes; 07.02.2017
comment
Зачем переходить в режим просмотра? Более простые движения, кажется, делают это :nnoremap <leader>( bi(<esc>eli)<esc> Или я что-то пропустил? Кстати очень хороший ответ. - person Titou; 16.01.2018

Surround.vim

person Ahmed Kotb    schedule 09.11.2011

Почему бы не использовать :s// (поиск и замена)?

Eg:

:s/sunny/(&)/

Вы, вероятно, имеете в виду что-то еще, но я не могу понять из вашего вопроса, что именно.

(& — сокращение для совпавшего текста)


В стороне: чтобы автоматизировать это, вы можете записать такой макрос: (с курсором в начале sunny):

  • qq - начать запись макроса в регистр q
  • ye - дергать в конец слова (в данном случае sunny) - может также yE и т.д.
  • : - войти в командный режим
  • Ctrl+R, ", вставьте скопированный текст
  • /(&)/ - завершить команду, как описано выше. Командная строка теперь будет читать :s/sunny/(&)/
  • enter - запустить команду, которая добавляет скобки.
  • q - остановить запись макроса

Теперь, если вы перейдете в начало другого слова, вы можете ввести @q для запуска макроса. Ничего в макросе не относится к слову sunny, поэтому он должен работать с чем угодно.

Вы можете обновить его, чтобы он работал в середине слова, сначала выполнив b или около того. Вы поняли идею. Вы также можете сохранить и восстановить позицию курсора, которую легко добавить (например: mz в начале и `z в конце).

person jwd    schedule 09.11.2011
comment
Потому что вы в конечном итоге дважды набираете слово, которое уже написано, когда вам нужно выделить его и поместить в круглые скобки. - person Titou; 04.05.2017
comment
Чтобы не вводить его дважды, вы можете скопировать его (yw), а затем вставить в свою команду (q: и отредактировать как обычно). Конечно, этот процесс тоже можно автоматизировать. - person jwd; 14.07.2021

Вы можете использовать следующие команды:

cw(<C-r><C-o>")<ESC>

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

Перед изменением:

word

затем используйте команду:

cw\enquote{<C-r><C-o>"}<ESC>

Конечный результат:

\enquote{word}
person vasconssa    schedule 13.08.2018
comment
Это блестяще. Вы также можете пометить текст v, а затем, очевидно, использовать только c(<C-r><C-o>")<ESC>. Вставка регистра по умолчанию или безымянного регистра, содержащего текст последнего удаления или копирования (см. :help i_^r), в последнюю позицию курсора (:help ^o) и немедленная вставка закрывающей скобки, весьма удобна. - person AdamKalisz; 18.11.2019

Я предпочитаю не использовать какие-либо плагины и хочу, чтобы все было ограничено моими точечными файлами для легкой переносимости. Самый простой способ, который я могу придумать, это просто записать его и воспроизвести. Если вы планируете использовать его чаще между сеансами, вы также можете сопоставить ключ в своем .vimrc, но мне это не нужно (и я действительно плохо понимаю, какое нажатие клавиши сопоставлять).

Предполагая, что вы разбираетесь в vim на уровне новичка, скажем, у меня есть строка (для простоты), которую я хочу заключить в квадратные скобки. например

hello world

Перейдите в обычный режим. q1, чтобы начать запись. Теперь сделайте следующее

ESC ^i[ ESC $a] ESC

Это оставит текущую строку в скобках. Теперь вы можете выбрать любую строку и нажать @1, чтобы повторить ее.

Если, например, вы хотите, чтобы текущее слово было заключено в скобки, просто запишите и воспроизведите следующий рецепт:

ESC bi[ ESC ea] ESC

Вы, конечно, можете попытаться оптимизировать нажатия клавиш, но пока это мне подходит.

person zakishaheen    schedule 19.07.2014

Я знаю, что это старый вопрос, но такое сложное решение, подобное этому, здесь еще не упоминалось, и я уверен, что оно может кому-то помочь. В моем файле .vimrc есть такая строка:

xnoremap <silent> ( <ESC>:let p = &paste<CR>:set paste<CR>:let a = line2byte(line('.')) + col('.')<CR>gvc()<ESC>:if getregtype() ==# 'V'<CR>call setreg('"', substitute(@", '\n$', '', ''), 'c')<CR>endif<CR>P:exe "goto ".a<CR>:exe "let &paste=".p<CR>

Достаточно выделить текст в визуальном режиме и нажать (. Это сопоставление работает также для линейного и блочного визуального режима.

Как это работает?

<ESC> выйдет из визуального режима

:let p = &paste<CR>:set paste<CR>...:exe "let &paste=".p<CR> гарантирует, что макрос будет выполняться в режиме вставки (поскольку автоотступ и подобные улучшения могут включать некоторые дополнительные пробелы, которые нам не нужны), в то время как статус вставки после макроса останется таким же, как и до выполнения макроса.

:let a = line2byte(line('.')) + col('.')<CR> найдет текущее смещение в байтах (на основе 1)

gv повторно выделит ранее выделенный текст

c удалит выделение и переведет нас в режим вставки, чтобы заменить выделение

()<ESC> поместит нужные скобки и выйдет из режима вставки

:if getregtype()==#'V'<CR>call setreg('"',substitute(@",'\n$','',''),'c')<CR>endif<CR> удалит конечный \n из безымянного (") регистра и изменит его тип на посимвольный, но только если он был построчным до этого (чтобы можно было вставлять из реестра в круглых скобках)

P вставит ранее замененный текст в круглые скобки

:exe "goto ".a<CR> вернет курсор в предыдущую позицию (goto использует смещение, основанное на 0, поэтому нам не нужно увеличивать ранее записанную позицию на единицу из-за вставленной левой скобки)

person Michal    schedule 11.09.2018

Для чего-то подобного, вероятно, лучше играть с диапазонами и группами, чем использовать внешние плагины:

:%s~\v(\w{5}) ~(\1) ~g

приведенный выше поиск слова из 5 букв, за которым следует пробел, группирует совпадение с помощью () и заменяет его круглыми круглыми скобками вокруг сгруппированного совпадения.

person gts    schedule 23.12.2013

Еще один полезный лакомый кусочек, которого я еще не видел в других ответах:

В сопоставлении используйте expand("<cword>") (или любые другие подобные <cWORD>, <cexpr> и т. д.). Это дает вам доступ к слову под курсором.

Например, чтобы заменить все вхождения в текущей строке слова под курсором версиями в скобках:

nnoremap <leader>( :execute "s!" . expand("<cword>") . "!(&)!g"<CR>

Есть некоторые недостатки:

  • Если в <cword> есть восклицательный знак, это прерывается (конечно, вы можете выбрать другой символ s///).
  • Вы не можете заменить только одно слово под курсором. Вы можете сделать первое в строке (по умолчанию) или все вхождения в строке (как указано выше, с флагом /g). Вы даже можете сделать все вхождения в файле с помощью %s....
person jwd    schedule 25.07.2020

Проверьте vim-sandwich

Если вы использовали Surround.vim раньше, вы даже можете заставить vim-sandwich использовать раскладки Surround.vim

Tbh единственное, что заставило меня переключиться с Surround.vim, это то, что vim-sandwich имеет ближайший парный оператор.

<сильный>| - курсор

Text User input in normal mode
[ { ( | ) } ] dsb
[ { | } ] dsb
[ | ] dsb
person 3nuc    schedule 09.06.2021