Многострочное редактирование в VIM, как в Sublimetext?

133

Я начал использовать gvim и не совсем понимаю, как работает многострочное редактирование в gvim.

Например:

Оригинальный текст:

asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

ctrl + q, jjjjjj, $ все выбрано, затем я нажимаю I, чтобы выполнить многострочную вставку.

Я намерен вставить кавычки, как в первой строке, а затем нажать Esc:

asd "asd asd" asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

Что произошло? Я ожидал поведения, аналогичного поведению sublimetext:

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

Если вы не знаете, как это работает, он просто повторяет действия для каждой строки. Как этого добиться? И что здесь делает vim?

AlfredoVR
источник
Просто запишите макрос клавиатуры, чтобы изменить первую строку, а затем воспроизведите макрос для всех остальных строк.
high5

Ответы:

215

Сделайте себе одолжение, отказавшись от уровня совместимости с Windows.

Обычный ярлык для входа в режим визуального блока - <C-v>.

Другие занимались записью макросов, вот еще несколько идей:

Использование только режима визуального блока .

  1. Наведите курсор на второе слово:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Нажмите, <C-v>чтобы войти в режим визуального блока и разверните свой выбор вниз:

    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    
  3. Нажмите, I"<Esc>чтобы получить:

    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  4. Наведите курсор на последний символ третьего слова:

    asd "asd as|d| asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  5. Нажмите, <C-v>чтобы войти в режим визуального блока и разверните свой выбор вниз:

    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    
  6. Нажмите, A"<Esc>чтобы получить:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

С режимом визуального блока и Surround.vim .

  1. Наведите курсор на второе слово:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Нажмите, <C-v>чтобы войти в режим визуального блока и разверните свой выбор вниз и вправо:

    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    
  3. Нажмите, S"чтобы окружить ваш выбор ":

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

С визуально-линейным режимом и :normal.

  1. Нажмите, Vчтобы выделить всю строку и развернуть ее вниз:

    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    
  2. Выполните эту команду: :'<,'>norm ^wi"<C-v><Esc>eea"<CR>чтобы получить:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    
    • :norm[al]позволяет выполнять команды в обычном режиме для ряда строк ( '<,'>часть автоматически добавляется Vim и означает «действовать в выбранной области»)

    • ^ помещает курсор на первый символ строки

    • w переходит к следующему слову

    • i"вставляет "перед курсором

    • <C-v><Esc>это способ Vim ввести управляющий символ в этом контексте, здесь он <Esc>используется для выхода из режима вставки

    • ee переходит в конец следующего слова

    • a"добавляет "после курсора

    • <CR> выполняет команду

    Используя Surround.vim, приведенная выше команда становится

    :'<,'>norm ^wvees"<CR>
    
romainl
источник
7
Для шагов 4 и 5 я бы рекомендовал нажать, gvчтобы вернуть ваш предыдущий визуальный выбор, а затем переместиться по горизонтали, возможно, с помощью 2e. (Чем больше строк, тем ценнее gv!)
joeytwiddle
4
Surround.vim использует маленький sв нормальном режиме, но большой Sв визуальном, поэтому на шаге 3 метода Surround.vim нажатия клавиш должны быть S"
такими
1
Пункт 3 visual-block + Surround.vim должен быть S", а неs"
zool
1
Вместо шагов 5 и 6 режима визуального блока вы можете просто поставить курсор после третьего слова и нажать ..
Jonas
2
Это круто, но это работает только в некоторых случаях, когда символы, которые вы хотите редактировать в разных строках, находятся в одном и том же горизонтальном положении в каждой строке, а отредактированные строки идут одна за другой. Не можем мы выбрать, где войти в режим редактирования, в какой строке в Vim? Мы можем в Sublim ... РЕДАКТИРОВАТЬ: На самом деле, второй ответ - это то, что я искал
Александр Бурлье,
30

Это некоторые хорошие готовые решения, приведенные выше, но мы также можем попробовать некоторые плагины, которые предоставляют несколько курсоров, например Sublime.

Думаю, это выглядит многообещающим:

На какое-то время он казался заброшенным, но в 2014 году в него были внесены некоторые изменения.

Он довольно мощный, хотя мне потребовалось некоторое время, чтобы привыкнуть к потоку (который довольно похож на Sublime, но все же модальный, как Vim).

По моему опыту, если у вас установлено много других плагинов, вы можете столкнуться с некоторыми конфликтами!

Есть и другие попытки реализовать эту функцию:

Не стесняйтесь редактировать, если заметите, что какие-либо из них претерпевают улучшения.

joeytwiddle
источник
Похоже, что github.com/osyo-manga/vim-over на данный момент самый активный из всех.
Вернайт,
Отлично, это то, что я искал
Александр Бурлье
1
После тестирования большинства из них, hlissner / vim-multiedit кажется лучшим AFAIAC
Alexandre Bourlier
1
Проверьте mg979 / vim-visual-multi как хорошую замену vim-multiple-
cursors
29

В Vim есть несколько способов сделать это. Я не знаю, какие из них больше всего похожи на Sublime Text.


Первый - в режиме многострочной вставки . Поместите курсор на вторую букву «a» в первой строке, нажмите Ctrl-V, выберите все строки, затем нажмите Iи заключите в двойные кавычки. Нажатие <esc>повторит операцию на каждой строке.


Второй - через макросы. Поместите курсор на первый символ и начните запись макроса с помощью qa. Перейдите вправо с помощью llll, войдите в режим вставки с помощью a, поставьте двойные кавычки, выйдите из режима вставки и вернитесь в начало строки с помощью <home>(или аналогичного). Нажмите, jчтобы перейти на одну строку вниз. Остановите запись с помощью q. А затем воспроизведите макрос с помощью @a. Несколько раз.


Вам подходит какой-либо из вышеперечисленных подходов?

ладья
источник
15

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

:g/<search>/.<your ex command>

пример:

:g/foo/.s/bar/baz/g

Приведенная выше команда находит все строки, в которых есть foo, и заменяет все вхождения bar в этой строке на baz.

:g/.*/

буду делать на каждой строчке

srini.venigalla
источник
1
Это настолько полезно, что я этого не знал. Кажется настолько мощным и умным сочетанием команд.
0xc0de
Для удобства я написал небольшую функцию, которая берет слово под курсором (или визуально выделенное слово), запрашивает замену и затем запускает :gкоманду, описанную здесь. Мне нравится использовать /gcдля запроса «подтверждений», чтобы я мог нажимать yили nдля каждой замены, или aдля изменения их всех.
joeytwiddle
11
Ctrl-v ................ start visual block selection
6j .................... go down 6 lines
I" .................... inserts " at the beginning
<Esc><Esc> ............ finishes start
2fdl. ................. second 'd' l (goes right) . (repeats insertion)
SergioAraujo
источник
На шаге 3 Iне могу войти в режим вставки, знаете почему это происходит?
Ninja
Попробуйте загрузить vim без плагинов: vim -u NONEи попробуйте снова выполнить желаемое действие, это может быть какая-то карта или плагин, изменяющий поведение вашего vim.
SergioAraujo 05
6

Не знаю, что vimпроисходит, но это интересный эффект. То, как вы описываете то, что вы хотите, больше похоже на работу макросов ( :help macro). Что-то вроде этого будет делать то, что вы хотите с макросами (начиная с нормального режима):

  1. qa: Записать макрос для aрегистрации.
  2. 0w: 0перейти в начало строки, wперейти на одно слово.
  3. i"<Esc>: Войти в режим вставки, вставить "и вернуться в нормальный режим.
  4. 2e: Переход к концу второго слова.
  5. a"<Esc>: Добавить ".
  6. jq Перейти к следующей строке и завершить запись макроса.

Взяты вместе: qa0wi"<Esc>2ea"<Esc>

Теперь вы можете выполнить макрос с помощью @a, повторить последний макрос с помощью @@. Чтобы применить к остальной части файла, сделайте что-то вроде того, 99@aчто предполагает, что у вас не более 99 строк, выполнение макроса завершится, когда он достигнет конца файла.

Вот как добиться желаемого visual-block-mode(начиная с обычного режима):

  1. Перейдите туда, где вы хотите разместить первую цитату.
  2. Enter visual-block-mode, выберите строки, на которые вы хотите повлиять, Gчтобы перейти в конец файла.
  3. Хит I"<Esc>.
  4. Перейдите к следующему месту, в которое вы хотите вставить ".
  5. Вы хотите повторить то, что вы только что сделали, поэтому простого .будет достаточно.
Тор
источник
4
Нет необходимости в 99 @ a. Если вы хотите запускать макрос в каждой строке файла, попробуйте:% norm! @a.
Ладья
Без точек (это просто концы предложений, а не часть команд)
Ладья
9999@aможет быть уродливым, но его намного легче набрать, :%norm! @aи он не запускается повторно в строке, которую вы только что отредактировали. Все равно хорошо это знать. :)
joeytwiddle
0

Мое решение - использовать эти 2 сопоставления:

map <leader>n <Esc><Esc>0qq
map <leader>m q:'<,'>-1normal!@q<CR><Down>

Как их использовать:

  1. Выберите свои линии. Если я хочу выбрать следующие 12 строк, я просто нажимаюV12j
  2. Нажмите <leader>n
  3. Внесите изменения в строку
  4. Убедитесь, что вы находитесь в нормальном режиме, а затем нажмите <leader>m

Чтобы внести еще одно изменение, вам не нужно делать выбор снова. Просто нажмите <leader>n, внесите изменения и нажмите, <leader>mчтобы применить.


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

  • <Esc><Esc>0qq Выйдите из визуального выделения, перейдите в начало строки и начните запись макроса.

  • q Остановите запись макроса.

  • :'<,'>-1normal!@q<CR> От начала визуального выделения до строки перед концом воспроизведите макрос на каждой строке.

  • <Down> Вернитесь к последней строке.


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

vmap <leader>m <Esc><Esc>0qq
nmap <leader>m q:'<,'>-1normal!@q<CR><Down>

Хотя это лишает вас возможности сделать еще одно редактирование. Вам придется повторно выбрать свои строки.

willmcpherson2
источник