Кілька курсорів у потрібному місці


14

Я використовую плагін vim-multiple-cursors .

Я хотів би поставити курсори саме там, де я хочу. Наприклад ( [x]позиції курсору):

Lorem ipsum dolor sit amet[1], consectetur adipiscing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna[2]
aliqua.

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

Чи є щось подібне у VIM? З цим плагіном чи іншим.

EDIT

Після коментаря, мій інтерес до цього виявився при спробі записати
\section[My first section in this book]{My first section in this book}
у .texфайл. Моя перша реакція полягала в тому, щоб написати, \section[]{}а потім поставити два курсори для того, щоб написати одне і те ж всередині []та {}.

Іншим прикладом може бути додавання _someStuffпісля декількох імен змінних. Наприклад, перетворіть це:

variable1 = 2
my_variable2 = 12
var3 = 14

в це:

variable1_someStuff = 2
my_variable2_someStuff = 12
var3_someStuff = 14

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



1
Я думаю, що важливе питання, яке потрібно задати, - чому ти хочеш це робити? Що ти намагаєшся зробити? Використання декількох курсорів насправді не "слідує за способом Vim", мабуть, є інший спосіб зробити те, що ви хочете, принаймні настільки ефективно, використовуючи вбудовані функції.
statox

@statox. Див. Редагування. Я наводив два приклади, які мені спадали на думку. Другий я можу виконати за допомогою плагіна vim-multiple-cursors, але перший я не можу, принаймні легким способом.
tomasyany

@ Nobe4 Спасибі, другий сценарій це зробив.
tomasyany

Відповіді:


30

Використання декількох курсорів не є річчю Віммера

Як я вже говорив у коментарях із використанням декількох курсорів (навіть із плагіном) насправді не "слідує за способом Vim", я повністю розумію, що це привабливо для когось із Sublime-Text, але часто можна знайти альтернативи, які є принаймні настільки ж ефективні із вбудованими функціями Vim.

Звичайно, знайти ці альтернативні рішення не завжди просто, а іноді потрібен час, але це стане простішим з вашим досвідом Vim, і ви побачите, що з часом кілька курсорів вам здадуться абсолютно марними.

Це здорово, але як я можу знайти альтернативний спосіб?

Універсальної відповіді немає, оскільки це багато залежить від того, що ви намагаєтеся зробити, я просто спробую дати кілька підказків про перші речі, які слід спробувати:


Командна точка .

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

Сила цієї команди полягає в тому, що остання зміна може бути дією, що працює над символом, рядком або цілим файлом. Наприклад, зміна може бути обмежена моментом введення режиму вставки та моментом повернення до звичайного режиму.

Зважаючи на це, легко зробити те, що ви хотіли зробити з мультикурсором:

  • Спочатку давайте налаштуємо наше середовище: напишемо так, як ви запропонували

    \section[]{}

  • Потім внесіть зміни, що повторюються . Курсор увімкнено }, натисніть, F[щоб повернутися до [символу. Потім перейдіть в режим вставки з iі введіть My first section in this bookі поверніться до звичайного режиму за допомогою ESC:

    \section[My first section in this book]{}

  • І ось ось магічна частина: Давайте f{наберемо курсор на {символі та натисніть, .щоб повторити останню зміну:

    \section[My first section in this book]{My first section in this book}

Усі завдання команди крапки - це навчитися робити повторювані зміни: це буде з виправленням Vim, але головне - зрозуміти, як зробити зміни повторюваним способом.

Наприклад, щоб вставити крапку з комою в кінці рядка, яку ви бажаєте використовувати A;замість $a;. Чому?

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

ПРИМІТКА Чарівна формула у Vim така n.. По-справжньому класним робочим процесом є:

  • шукайте місце, яке ви хочете змінити /pattern
  • зробіть свою повторювану редагування
  • використовуйте nдля переходу до наступного місця для редагування
  • використовувати .для повторення редагування
  • повторіть останні два кроки: ви король світу (або принаймні редагування)

макроси

Макроси - ще один надзвичайно важливий інструмент Vim, оскільки він дозволяє записати послідовність натискань клавіш і повторити її, як ніби ви ввели її ще раз.

Я використаю, як приклад, ваш другий випадок використання:

variable1 = 2
my_variable2 = 12
var3 = 14

Ще раз важливо - дізнатися, як зробити свої макроси ефективними (я наведу приклад зустрічного відразу після):

  • Покладіть курсор на слово variable1і починайте записувати ваш макрос qq. Це означає "почати записувати всі мої майбутні натискання клавіш у реєстрі з назвою q".

  • Почніть редагувати текст:

    • 0 йти на початку рядка
    • e йти в кінці першого слова
    • a додати після курсору
    • .someStuff додати шуканий текст
    • <Esc> щоб зупинити вставку
    • j перейти на наступний рядок
    • q щоб припинити запис макросу
  • Ви отримаєте:

variable1.someStuff = 2
my_variable2 = 12
var3 = 14
  • Тепер ви можете використовувати макрос для повторення редагування. Оскільки ви перебуваєте в правому рядку для редагування, ви можете просто виконати макрос за допомогою @q. Оскільки ми хочемо виконати його двічі, ви можете використовувати його, 2@qі ви отримаєте такий результат:
variable1.someStuff = 2
my_variable2.someStuff = 12
var3.someStuff = 14

ПРИМІТКА 1. Як ви могли помітити, використання 0eaна початку макросу було дуже важливим. Дійсно, якби ви поставили курсор в кінці першого слова перед тим, як записати макрос і знову виконати його, ваш результат був би таким:

variable1.someStuff = 2
my_variable2 = 12.someStuff
var3 = 14.someStuff

Як ваш курсор текст був би вставлений у положення курсору після зміни рядка (тобто кінець рядка в цьому випадку)

ПРИМІТКА 2 Макроси надзвичайно потужні, і ви навіть можете створювати рекурсивні макроси, коли вам зручно. Тут міг бути ваш макрос:

`0ea.someStuff<Esc>j@q`

Фінал @qби назвав макрос сам по собі, а не використовувати 2@q; ви просто використали б, @qі вся робота була б виконана.


візуальний блок

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

li.one   a{ background-image: url('/images/sprite.png'); }
li.two   a{ background-image: url('/images/sprite.png'); }
li.three a{ background-image: url('/images/sprite.png'); }

Що робити, якщо ви перемістили спрайтів з imagesдо components?

Ну ви можете помістити курсор на iз imagesі натисніть <C-v>. Це запустить режим візуального блоку, який дозволяє вибрати блоки. Тепер ви можете ввести t/ слово, яке ви хочете змінити, і 2jвибрати всі зустрічі слова.

Після цього вам просто потрібно набрати, cщоб змінити слово, а потім components. Коли ви вийдете з режиму вставки, ви побачите:

li.one   a{ background-image: url('/components/sprite.png'); }
li.two   a{ background-image: url('/components/sprite.png'); }
li.three a{ background-image: url('/components/sprite.png'); }

Глобальна команда

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

Синтаксис такий:

:[range] g / pattern / command

Детальніше про [range]параметр див :h :range. Я не буду деталізувати це тут, я просто нагадаю, що %представляє весь файл, '<,'> представляє останній вибір і 1,5представляє рядки 1 - 5 файлу.

Цей параметр визначає рядки, які будуть оброблятися глобальною командою. Якщо діапазон не вказаний, глобальна команда буде використовувати %за замовчуванням.

Аргумент [pattern] - це шаблон пошуку, як ви звикли користуватися пошуковою системою. Оскільки вона інтегрує історію пошуку, ви можете залишити це поле порожнім, а глобальна команда використає останній шаблон пошуку в історії пошуку.

Нарешті, параметр [command] - це колишня команда, як ви, ймовірно, звикли.

Зараз поведінка глобальної команди досить проста:

  • Ітерація через усі рядки, визначені параметром [діапазон]
  • Якщо поточний рядок відповідає заданому шаблону, застосуйте команду

Оскільки параметр [command] є колишньою командою, ви можете зробити багато речей. Візьмемо наступний псевдо-код, який не дуже цікавий і містить багато повідомлень про налагодження:

var myList  = null
var i       = 0

myList = new List()
echo "List instantiated"

for (i=0; i<10; i++)
    myList.Add(i)
    echo i . " added to the list"

echo "end of for loop"

Тепер скажемо, що ви впевнені, що цей код працює, і ви хочете видалити ці непотрібні echoзаяви:

  • Ви можете застосувати свою глобальну команду до всього файлу, тому вам доведеться додати команду до %(або нічого, оскільки %це діапазон за замовчуванням).

  • Ви знаєте, що рядки, які потрібно видалити, всі відповідають шаблону echo

  • Ви хочете видалити ці рядки, тому вам доведеться використовувати команду, :delete яку також можна скоротити якd

Тож вам просто доведеться використовувати таку функцію:

:%global/echo/delete

Що також можна скоротити як

:g/echo/d

Зауважте, що %зник, globalскорочено як gі deleteяк d. Як ви можете собі уявити, результат такий:

var myList  = null
var i       = 0

myList = new List()

for (i=0; i<10; i++)
    myList.Add(i)

ПРИМІТКА 1. Важливим моментом, який знадобився певний час, щоб зрозуміти, що normalкоманда - це колишня команда, що означає, що ви можете використовувати її з глобальною командою. Це може бути справді потужним: скажімо, що я хочу дублювати всі рядки, що містять відлуння, мені не потрібен макрос або навіть магічна формула n.. Я просто можу використовувати

:g/echo/normal YP

І вуаля:

var myList  = null
var i       = 0

myList = new List()
echo "List instantiated"
echo "List instantiated"

for (i=0; i<10; i++)
    myList.Add(i)
    echo i . " added to the list"
    echo i . " added to the list"

echo "end of for loop"
echo "end of for loop"

ПРИМІТКА 2 "Ей, що, якщо я хочу використовувати свою команду в рядках, які не відповідають певній схемі?"

globalмає протилежну команду, vglobalскорочену, vяка працює точно так, globalза винятком того, що команда буде застосована до рядків, які не відповідають параметру [pattern]. Таким чином, якщо ми звернемось

:v/echo/d

На попередньому прикладі ми отримуємо:

echo "List instantiated"
    echo i . " added to the list"
echo "end of for loop"

deleteКоманда була застосована на лініях , які не містяться echo.


Тут я сподіваюсь, що ці кілька підказок дадуть вам ідеї щодо того, як позбутися від мульти курсорного плагіна та використовувати Vim способом Vim ;-)

Як ви можете уявити, ці приклади досить прості і просто зроблені для того, щоб продемонструвати, що коли ви слідуєте за способом Vim, вам дуже рідко потрібно кілька курсорів. Моя порада була б, коли ви стикаєтесь із ситуацією, коли ви вважаєте, що це буде корисно, запишіть її та пізніше піде трохи часу, щоб знайти краще рішення. У 99% часу ви з часом знайдете швидший / ефективніший спосіб зробити це.

Також я повторюся ще раз, але дуже рекомендую вам прочитати Практичний Vim від Дрю Ніла, оскільки ця книга не про "Як зробити те чи це у Vim", це про "Як навчитися думати по Vim" що дозволить вам добре побудувати власне рішення своїх майбутніх проблем.


PS Особлива подяка @Alex Stragies за його роботу з редагування та виправлення, які він вніс на цю довгу посаду.


Дуже повна відповідь. Я насправді знав усі ці команди, але ніколи не думав використовувати їх так ... Я думаю, мені потрібно більше практики. Однак я мушу сказати, що іноді "vim-way" займає більше часу, ніж просто використання якогось плагіна (наприклад, ваш CSS-приклад можна зробити набагато швидше за допомогою плагіна, який я згадав), а іноді він займає набагато коротше (насправді величезна кількість більшість разів vim швидше, ніж будь-який текстовий редактор, якщо його правильно використовувати).
tomasyany

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

1
@tomasyany: Дійсно, іноді використання "vim way" може здатися довше (я не можу порахувати, скільки разів витрачаю більше часу на створення робочого макросу, ніж якби я робив зміни вручну), але з практикою це в підсумку стає швидшим. Я використовую Vim лише один рік, і я (дуже) далеко не експерт, але я можу відчути, що моє редагування постійно покращується, коли я практикую.
statox

1
Напевно, слід згадати і gnтекстовий об’єкт. Він розглядає деякі випадки використання декількох курсорів. Знайдіть /, потім dgnабо cgn, потім повторіть із ..
Джастін М. Кіз

@Justin Я не дуже знайомий, gnя спробую його додати після. Дякую за голову!
statox

5

Надані вами випадки використання мені здаються бажати знати .ключову команду (повторити останню команду редагування)

  • Перейдіть на перше місце, натисніть i, вставте текст,<ESC>
  • перейдіть до місця 2, натисніть .(Dot) ==> Вставлений ідентичний текст
  • Щоб перемістити сюди один рядок і знову вставити його (коли вставляєте в послідовні рядки), натисніть <ALT>-j.

Ваш текстовий приклад для мене вирішує:

I\section[]{}<ESC>hhiMy first Sec...<ESC>lll.


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

1
Ну а ваше запитання (після того, як ви додали бажані випадки використання) нагадало мені: "Мені дуже подобаються мої ножиці, і я хочу закрутити їх гвинтами. Скажіть, як". І мені вказують на вишукане використання викрутки;) (я додав як відповідь, тому що я не знаю, як робити форматування в коментарях)
Alex Stragies

4

Більше способів Vim.

Перше завдання:

\section[foobar baz]{foobar baz}

Робочий процес:

\section[]{}
hh
ifoobar baz<Esc>
$.

Друге завдання:

variable1 = 2
my_variable2 = 12
var3 = 14

Команда:

3:norm ea_somestuff

Результат:

variable1_somestuff = 2
my_variable2_somestuff = 12
var3_somestuff = 14
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.