Vim: вставляйте однакові символи через кілька рядків


306

Іноді хочеться відредагувати певний візуальний блок тексту в декількох рядках.

Наприклад, я б взяв текст, який виглядає приблизно так:

name
comment
phone
email

І зробити так, щоб це виглядало так

vendor_name
vendor_comment
vendor_phone
vendor_email

В даний час так, як я це зробив би зараз ...

  1. Виберіть усі 4 рядкові рядки блоку, натиснувши, Vа потім jчотири рази.
  2. Відступ с >.
  3. Поверніться один лист із h.
  4. Перейдіть до блоку візуального режиму за допомогою Ctrlv.
  5. Виберіть чотири ряди вниз, натиснувши jчотири рази. У цей момент ви вибрали 4х1 візуальні блоки пробілів (чотири рядки та один стовпець).
  6. Натисніть C. Зауважте це в значній мірі з відступом ліворуч на один стовпець.
  7. Введіть " vendor_"без цитати. Зауважте додатковий простір, який нам довелося повернути.
  8. Натисніть Esc. Це один з небагатьох разів, який я використовую, Escщоб вийти з режиму вставки. Ctrlcредагував би лише перший рядок.
  9. Повторіть крок 1.
  10. Вставте інший спосіб за допомогою <.

Мені не потрібно відступати, якщо перед словами є хоча б один стовпець пробілу. Мені не знадобиться пробіл, якби мені не довелося очищати візуальний блок c.

Але якщо мені доведеться очистити, то чи є спосіб зробити те, що я виконував вище, не створюючи потрібного пробілу з відступом?

Крім того, чому редагування декількох рядків одночасно працює лише шляхом виходу з режиму вставки із Escзакінченням Ctrlc?


Ось більш складний приклад:

name    = models.CharField( max_length = 135 )
comment = models.TextField( blank = True )
phone   = models.CharField( max_length = 135, blank = True )
email   = models.EmailField( blank = True )

до

name    = models.whatever.CharField( max_length = 135 )
comment = models.whatever.TextField( blank = True )
phone   = models.whatever.CharField( max_length = 135, blank = True )
email   = models.whatever.EmailField( blank = True )

У цьому прикладі я би виконував вертикальний візуальний блок над ., а потім знову вставляв його під час вставки, тобто вводив .whatever.. Сподіваємось, тепер ви побачите недолік цього методу. Я обмежуюся лише вибором стовпця тексту, який однаковий у вертикальному положенні .


9
Кращий спосіб: ":% s / ^ / vendor_ /"
Пол Томблін

1
Дякуємо за відповідь. Це працює, якщо я хочу лише додати слово до кожного рядка. Але метод, який я використовую, можна виконати в будь-якій позиції. Дозвольте додати ще один мій приклад із більш складним прикладом.
hobbes3

3
Потім виділіть рядки, які ви хочете змінити, за допомогою shift-V і введіть відповідну команду пошуку та заміни - у другому прикладі,:s/models\./\0whatever./
Пол Томблін

Багато способів досягти сказаного. Щоб повністю відповісти на всі частини питання, тоді частина 1) або регулярний вираз, або візуальний режим, я редагую esc чудово, як пропонується у відповідях (я віддаю перевагу візуальному підбору в GVIM). У частині 2) макрос, мабуть, найпростіший, як пропонує Брайан Ніл. Найкращий ресурс, про який я знаю, для всіх цих типів "як" - це "Практичний Vim" від Дрю Ніл. Відмінна швидке зчитування та невелика посилання, коли ви забудете формулу. Сподіваюся, що ця рекомендація комусь допоможе, це буде варте зусиль для багатьох користувачів vim.
arcseldon

@Paul: І якщо ви підрахунку натискань клавіш , ви можете замінити \0з &.
icktoofay

Відповіді:


912
  1. Перемістити курсор в nін name.
  2. Увійдіть у режим візуального блоку ( Ctrlv).
  3. Натисніть jтричі (або 3j).
  4. Преса I(капітал i).
  5. Введіть vendor_. Примітка: оновиться екран лише в першому рядку - до тих пір, поки не Escбуде натиснуто (6.), після чого всі рядки будуть оновлені.
  6. Натисніть Esc.

міні-екранізація, що демонструє метод

IПотрібно використовувати великі регістри i, а не малі , тому що малі iтрактуються як початок текстового об'єкта , що є досить корисним самостійно, наприклад для вибору всередині блоку тегів ( it):

міні-скріншот, що показує корисність текстового об’єкта "це"


12
Я не міг змусити це працювати в Windows (оскільки CTRL + V відображений для вставки в буфер обміну). Але Vim також відобразив це на Ctrl + Q для версії Windows.
Арнестіг

2
@ Ven: Vim протягом цього часу насправді не зайнятий - він просто чекає, коли ти натиснеш іншу клавішу, а згодом вимкнеться час. Два експерименти для вас: спочатку спробуйте натиснути клавішу втечі, а потім негайно натиснути іншу клавішу, наприклад, jабо ^L. Ви повинні побачити, що Вім врешті не був зайнятий; це просто чекало. По-друге, спробуйте змінити 'timeout'на нижчу величину, як-от 80(а не за замовчуванням 1000), і зауважте, що вона закінчується швидше.
icktoofay

1
@icktoofay Схоже, змінна, яку ви хочете встановити, timeoutlenне є timeout.
яз

4
@ANjaNA: Якщо там, де ви хочете вставити, все в одному стовпчику (наприклад, якщо цифри мають однакову довжину), ви можете використовувати ту саму техніку, крім натискання, Aа не I, яка буде вставлена ​​після вибраного блоку, а не раніше. Якщо ваші лінії різної довжини, це не працюватиме; Мені подобається використовувати заміну, що відповідає кінці кожного рядка для цього, наприклад, вибір деяких рядків та використання :s/$/inserted/.
icktoofay

3
Мені довелося натискати стрілку вниз після натискання клавіші esc, щоб це працювало
GeoSword

69

Інший підхід полягає у використанні команди .( dot) у поєднанні з I.

  1. Перемістіть курсор там, де ви хочете почати
  2. Натисніть I
  3. Введіть потрібний префікс (наприклад vendor_)
  4. Натисніть esc.
  5. Натисніть, jщоб перейти по лінії
  6. Введіть, .щоб повторити останнє редагування, автоматично вставляючи префікс знову
  7. Швидко чергуйте між jі.

Я вважаю цей метод часто швидше , ніж в режимі візуального блоку для невеликого числа доповнень і має додаткову перевагу , що , якщо вам не потрібно , щоб вставити текст на кожному рядку в діапазоні ви можете легко пропустити їх, натиснувши додаткові j«пд.ш. .

Зауважте, що для великої кількості суміжних доповнень блок-підхід чи макрос, ймовірно, будуть вищими.


Приємно бачити інший підхід.
Ібн Саїд

Я вважаю за краще це лише кілька рядків. Набагато простіше виконати ІМО.
Ден Бешард

Після того, як ви введете потрібний префікс, вам не потрібно натискати клавішу втечі?
iamnotsam

41
  1. Виберіть рядки, які ви хочете змінити CtrlV.
  2. Натисніть:

    • I: Вставте перед вибраним.
    • A: Додайте після вибраного.
    • c: Замініть вибране.
  3. Введіть новий текст.

  4. Натисніть, Escщоб застосувати зміни до всіх вибраних рядків.

4
Відмінно! Я б лише виділити останній крок Escдля номінантів VIM, як я - мені знадобилося певний час, щоб зрозуміти, що зміни поширюються "пізніше"!
Багз Зайчик

1
Приємно, теж не знав про варіанти "А" та "С".
hobbes3

Чому це не працює v? Я можу це зробити Ctrl+V --> A, але робити vвибір тексту не працює - Aдодається лише до цього рядка. Хіба вони не обидва? Також дуже дивно - Aдодається лише до кінця рядка ЯКЩО я розширюю візуальний блок до кінця рядка; в іншому випадку він додається там, де візуальний блок закінчується для кожного рядка. Це як би не визнає різниці між aта A.
Алекс Г

1
Мені потрібно було використовувати cзамість C, але це спрацювало чудово. Дякую
Тарол

29

Я використовував би макрос для запису своїх дій, а потім повторював би його.

  1. Поставте курсор на першу букву в імені .
  2. Натисніть, qqщоб почати запис у буфер q.
  3. Натисніть, iщоб перейти в режим вставки, введіть vector_ , а потім натисніть, Escщоб залишити режим вставки.
  4. Тепер натисніть, 0щоб повернутися до початку рядка.
  5. Тепер натисніть, jщоб спуститися.
  6. Тепер натисніть qзнову, щоб припинити запис.

Тепер у вас є гарний макрос.

Введіть 3@qдля виконання макросу три рази, щоб виконати решту рядків.


Спеціальний "q" (для "швидкого макросу"?)?
Пітер Мортенсен

Як можна зробити макрос стійким (працюючи протягом декількох сеансів)?
Пітер Мортенсен

@PeterMortensen Vim має функцію під назвою сеанси, яка зберігатиме буфери (та багато інших речей), які ви можете переглянути.
Брайан Ніл

27
:%s/^/vendor_/

чи я щось пропускаю?


Вам не вистачає факту, що це, ймовірно, підтекст у файлі з багатьма іншими рядками, у яких vender_префікс небажаний.
Ден Бешард

9
@dan Якщо потрібен лише підтекст, ви можете обмежити пошук набором номерів рядків, наприклад1,4s/^/vendor_/
Brad Koch

1
@BradKoch Цікаво. Мені не було відомо про обмеження числа рядків, за це дякую.
Ден Бешард

8
це цікаво, але що практичніше - це візуально заблокувати вибір Vі ввести :. Він додасть вираз ed, за допомогою :'<,'>якого редакція застосовуватиметься лише до виділення з:'<,'>s/^/vendor_/
Доланор

12

Оновлено січень 2016 року

Хоча прийнята відповідь є чудовим рішенням, насправді це дещо менше натискань клавіш, а масштаби краще - в принципі ґрунтуються на прийнятій відповіді.

  1. Перемістити курсор в nін name.
  2. Увійдіть у режим візуального блоку ( ctrlv).
  3. Натисніть 3j
  4. Натисніть I.
  5. Введіть vendor_.
  6. Натисніть esc.

візуальна ілюстрація

Зауважте, що в ньому менше натискань клавіш, ніж надана відповідь (порівняйте крок 3). Ми просто підраховуємо кількість j дій, які потрібно виконати.

Якщо у вас включені номери рядків (як показано вище), і ви знаєте номер рядка, до якого ви хочете перейти, то крок 3 можна змінити на #, Gде # - шуканий номер рядка.

У нашому прикладі вище це було б 4G. Однак при роботі з кількома номерами рядків явний підрахунок працює добре.


7

Я хотів прокоментувати багато рядків у якомусь конфігураційному файлі на сервері, який мав лише vi (без нано), тому візуальний метод був також громіздким. Ось як я це зробив.

  1. Відкрити файл vi file
  2. Показати номери рядків :set number!або:set number
  3. Потім використовуйте номери рядків, щоб замінити початок рядка на "#", як?

:35,77s/^/#/

Примітка: номери включно, рядки від 35 до 77, обидва включені будуть змінені.

Щоб відмежувати / скасовувати це, просто використовуйте :35,77s/^#//

Якщо ви хочете додати текстове слово як коментар після кожного рядка коду, ви також можете використовувати:

:35,77s/$/#test/ (для таких мов, як Python)

:35,77s/;$/;\/\/test/ (для таких мов, як Java)

кредити / довідки:

  1. /unix/84929/uncommenting-multiple-lines-of-code-specified-by-line-numbers-using-vi-or-vim

  2. /unix/120615/how-to-comment-multiple-lines-at-once


Це було ідеальним рішенням для мене, оскільки я часто використовую лише vim-tiny.
JSON C11

7

У вас також може бути випадок використання, коли ви хочете видалити блок тексту та замінити його.

Подобається це

Hello World

Hello World

До

Hello Cool

Hello Cool

Ви можете просто візуальним блоком вибрати "Світ" в обох рядках.

Тип c для зміни - тепер ви будете у режимі вставки.

Вставте потрібний матеріал і натисніть на втечу.

Обидва відбиваються вертикально. Він працює так само, як "Я", за винятком того, що замінює блок новим текстом замість того, щоб вставляти його.


6

Припустимо, у вас є цей файл:

something

name
comment
phone
email

something else
and more ...

Ви хочете додати "vendor_" перед "ім'ям", "коментарем", "телефоном" та "електронною поштою", незалежно від того, де вони відображаються у файлі .

:%s/\<\(name\|comment\|phone\|email\)\>/vendor_\1/gc

cПрапор запросить підтвердження. Ви можете це відкинути, якщо не хочете підказувати.


5

Альтернатива, яка може бути гнучкішою:

Приклад: для введення тексту XYZ на початку рядка

:%norm IXYZ

Що тут відбувається?

  • % == Виконати в кожному рядку
  • norm == Виконайте наступні клавіші в звичайному режимі
  • I == Вставити на початку рядка
  • XYZ == Текст, який потрібно ввести

Тоді ти б'єш Enter, і він виконує.

Специфічні для вашого запиту:

:%norm Ivendor_

Ви також можете вибрати певний діапазон:

:2,4norm Ivendor_

Або виконувати над обраним візуальним діапазоном:

:'<,'>norm Ivendor_

1
чи можна надсилати такі ключові послідовності, як <Esc>, перебуваючи у режимі вставки (норма Iabc <ESC>), щоб зробити ще цікаві речі?
батбрат

1
@batbrat Я щойно це зрозумів! Ви можете натиснути, ctrl-v ctrl-[щоб вставити "уникнутий Esc", який поверне вас у "звичайний режим" для вашої звичайної команди. Я щойно перевірив це '<,'>norm Iaa^[ysiw", де ^[знаходиться Esc.
Обрі Лавінь

4
Use Ctrl+V to enter visual block mode
Move Up/Down to select the columns of text in the lines you want to comment.
Then hit Shift+i and type the text you want to insert.
Then hit Esc, wait 1 second and the inserted text will appear on every line

чи працює цей метод для всіх версій vim чи потрібні плагіни vim? Причина, чому я прошу, це б / с, це іноді працює на деяких машинах, але іноді - ні. я не можу зрозуміти різницю. vim, який поставляється з git на Windows - я не можу змусити його працювати. на деяких машинах Linux i ubuntu та centos я не можу змусити його працювати. я мав успіх у кількох рідкісних випадках, але я не міг відтворити успіх. це таємниця. нічого не здається після того, як я натиснув ESC.
davidj411

як не дивно, це працює для мене зараз. нічого не змінилося, крім, можливо, зірок :), шукаючи рішення моєї проблеми, я знайшов щось на цій сторінці, хоча там згадується щось шукати в vim vim.wikia.com/wiki/Inserting_text_in_multiple_lines У Vim, перевірте, чи є у вас функція блокових операторів (I, A і більше), ввівши команду: version. Вихід повинен включати + visualextra.
davidj411

Я мав намір додати коментар загалом, а не до вашої відповіді. Більшість цих відповідей говорять те саме, але використовуючи різні слова. Моя запропонувала щось інше і включила посилання.
davidj411

2
  1. Ctrl + v для переходу в режим візуального блоку
  2. Виберіть лінії за допомогою стрілки вгору та вниз
  3. Введіть малі літери 3i( три рази натисніть на малі регістри I )
  4. I (прес-капітал I . Це переведе вас у режим вставки.)
  5. Напишіть текст, який ви хочете додати
  6. Esc
  7. Натисніть стрілку вниз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.