Основи множинних курсорів


55

Нещодавно я дізнався про це multiple-cursors, і це виглядає як дуже корисний пакет. Я переглянув документацію на оригінальному репо , але команди все ще виглядають трохи незрозуміло для мене.

Потім я переглянув це відео в Emacs Rocks !, і це відео чудове, але воно зосереджується в основному на тому, що multiple-cursorsздатне робити, а не на тому, як це зробити.

Чи є підручники, навчальні посібники чи приклади, які ілюструють його найпростіші функції?


4
Мені вдалося multiple-cursorsдуже швидко встати і працювати, просто прочитавши файл README. Моя рекомендація - просто вчитися mc/mark-next-like-this. Спробуйте це і ознайомтеся з тим, що це робить. Звідти поверніться до README кожного разу, коли у вас виникне запитання, яке починається з "Цікаво, чи можуть зробити декілька курсорів ..." Все це сказав, я думаю, що це більш базове введення, ніж скелі Emacs! відео буде корисним для початківців.
nispio

Повністю згоден! Абсолютно незрозуміло, як ним користуватися. Я просто маскую рядки, тоді роблю mc / edit-рядки з прив’язаними KBD (не через Mx, як зазначено на Github) Потім я бачу кілька курсорів, але вони просто зникають після будь-якого введення тексту
Діма Фомін

Відповіді:


19

На додаток до опису використання @bastibe, я використовую кілька курсорів, щоб додати або видалити текст з початку / кінця групи рядків:

  1. Перемістіть точку на початок чи кінець області, що цікавить
  2. дзвінок set-rectangular-region-anchor(прив’язаний до будь-якої клавіші, що вам подобається, я думаю, що пропозиція від Magnars була H-space, якщо у вас є гіпер ключ)
  3. Переміщайте точку вперед або назад по рядку ( C-nі C-p), поки у вас не з’явиться курсор на кожному рядку, який ви бажаєте редагувати
  4. Вставте або видаліть текст за потребою, необов'язково перемістившись до кінця рядка ( C-e), щоб внести зміни.

Ви можете використовувати forward-wordі forward sentenceт.д. для переміщення вперед і назад по рядках, що дозволяє редагувати четверте слово у кожному рядку, навіть якщо текст у кожному рядку не є однаковим.

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

  • C-u M-!ls / test-dat / pp5 / * fsaRETURN

    Це вставляє контексти каталогу pp5 в буфер. Я розміщую крапку !на початку лістингу:

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa
/test-dat/pp5/QCJB-22-5_Frag#90.fsa
/test-dat/pp5/ONGL-1-5_Frag#102.fsa
/test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Додайте курсори до кожного рядка за допомогою H-space, C-nx 4
  • дублювати кожен рядок с C-k C-y space C-y C-a

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa /test-dat/pp5/ONAB-6-5_Frag#89.fsa
!/test-dat/pp5/QCJB-22-5_Frag#90.fsa /test-dat/pp5/QCJB-22-5_Frag#90.fsa
!/test-dat/pp5/ONGL-1-5_Frag#102.fsa /test-dat/pp5/ONGL-1-5_Frag#102.fsa
!/test-dat/pp5/ONGL-1-5_Frag#78.fsa /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • обріжте перший розділ назви змінних з M-dx 3 C-d C-fx3 M-dx3 <-

ONAB-6-5 <-! /test-dat/pp5/ONAB-6-5_Frag#89.fsa
QCJB-22-5 <-! /test-dat/pp5/QCJB-22-5_Frag#90.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#102.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • потім оберніть фактичне ім'я файлу у функцію для його завантаження: read.file ( C-d" C-e")RETURN

ONAB-6-5 <- read.file("/test-dat/pp5/ONAB-6-5_Frag#89.fsa")
QCJB-22-5 <- read.file("/test-dat/pp5/QCJB-22-5_Frag#90.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#102.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#78.fsa")

І вуаля, ви перетворили список файлів у код, щоб прочитати цей список. Це насправді набагато складніше описати, ніж насправді зробити!


3
Якщо ви робите це те саме часто, ви можете зафіксувати його в макросі клавіатури. Клавіатура макросів і multiple-cursorsможе створити дійсно потужне поєднання.
nispio

@nispio погодився! Іноді я повторюю той самий процес, і макрос був би корисним. Однак часто в середині робочого потоку є невеликі відмінності, які потребують незначних змін, які б "зламали" макрос.
Тайлер

1
Ви можете часто точно описати місце, на яке курсор переходить, використовуючи регулярний вираз. У таких випадках використання phi-searchможе бути більш надійним, ніж навігація з такими командами, якM-f (x3)
nispio

@nispio впевнений, це залежить від ситуації. З послідовно структурованими іменами легко пересуватися словом. Я не використовував пошук у декількох курсорах, оскільки вбудовані команди пошуку Emacs крихкі з mc. Я не знав про це phi-search, це виглядає чудово!
Тайлер

22

У мене в основному є два випадки частого використання для multiple-cursors:

  • Замініть якусь рядок. Позначте один екземпляр рядка, а потім використовуйте mc/mark-next-like-thisта mc/mark-previous-like-thisпозначте більше його примірників. Потім я відразу натискаю, C-wщоб видалити кожен екземпляр, і замість цього напишу новий рядок. Я часто використовую це для перейменування змінної в коді.
  • Редагуйте кілька місць одночасно. Або позначте кілька екземплярів рядка, як і раніше, але скасуйте виділення (але не курсори) негайно C-g, або помістіть позначку та крапку в одному стовпчику різних рядків і використовуйте, mc/edit-linesщоб отримати один курсор на рядок. Тепер ви можете використовувати звичайні команди редагування, які працюють на кожному з цих курсорів.

Випадок першого використання особливо корисний для expand-region. Я er/expand-regionприв’язаний до C-j, і mc/mark-next-like-thisі mc/mark-previous-like-thisдо C->і C-<. Завдяки цьому я можу легко вибрати слово ввімкнено і негайно позначити наступне / попереднє виникнення цього слова.

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


Дякую @bastibe Якісь конкретні прив'язки, які ви multiple-cursors рекомендуєте або рекомендуєте, наприклад, mark-next-like-this& mark-previous-like-this?
Амеліо Васкес-Рейна

@ user815423426 як викладено у публікації, я використовую C->і C-<для, mark-next-like-thisі mark-previous-like-this.
Бастібе

чому б не використовувати стандартний M-% для пошуку та заміни ?
Діма Фомін

6

Я хотів би додати деякі додаткові речі, якими я іноді користуюся multiple-cursors.

Я виявив таке корисне:

iy-go-to-char

Іноді виникає потреба перейти до наступного #чи наступного ,чи якогось конкретного роздільника. Це особливо зручно, коли потрібно переміщувати різні кількості слів для кожного курсору. Він надає функції iy-go-to-charі iy-go-to-char-backward, які ви можете добре зв’язати та використовувати.

розширити-регіон

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

нестандартні речі

Це речі, які в моєму конфігурації просто є, але я вважаю корисними. Напевно, не написане мною.

Запрошення на введення
Я отримав цю інформацію від Magnars у відповідь на запит про введення різного рядка під кожен курсор. Код простий, але прив’язувати його до чогось і використовувати для декількох курсорів - це зручний спосіб вставити трохи різні речі в кожне місце.

(defun prompt-for-insert ()
  (interactive)
  (insert (read-string "Insert: ")))

Приріст номер у точці
Це або походить від SO, або emacswiki. Не впевнений, який. Це досить корисно самостійно, а також при використанні в поєднанні зmc/insert-numbers

(defun my-increment-number-decimal (&optional arg)
  "Increment the number forward from point by 'arg'."
  (interactive "p*")
  (save-excursion
    (save-match-data
      (let (inc-by field-width answer)
        (setq inc-by (if arg arg 1))
        (skip-chars-backward "0123456789")
        (when (re-search-forward "[0-9]+" nil t)
          (setq field-width (- (match-end 0) (match-beginning 0)))
          (setq answer (+ (string-to-number (match-string 0) 10) inc-by))
          (when (< answer 0)
            (setq answer (+ (expt 10 field-width) answer)))
          (replace-match (format (concat "%0" (int-to-string field-width) "d")
                                 answer)))))))

eval-and-substituse
Це надзвичайно потужно і дозволяє отримати декілька дійсно корисних біт-п'єс. Він оцінює те, що секпс знаходиться за курсором, і вставляє результат його оцінки.
Поєднайте його, multiple-cursors-numbersщоб, наприклад, вставити сили двох, або серію, яка переходить 0 1 2 0 1 2 0 1 2через кожну лінію чи щось таке. (Я обидва це зробив корисно) Або скористайтеся ним, s.elщоб виписати ці нудні конфігурації Java з речами за замовчуванням. Ви виписуєте кожен CONFIG_VALUE_VARIABLE, а потім перетворюєте його CONFIG_VALUE_VARIABLE = "configValueVariable"на біг s-camel-case.

(defun eval-and-replace ()
  (interactive)
  (let ((value (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" value))))

iy-go-to-char - це дуже корисно. Тільки те, що я шукав.
Генріх Хартманн

1
  1. Перейдіть до кінця * того, що ви хочете обрати.
  2. Натисніть C-S-bабо, M-S-bщоб вибрати назад, поки не буде вибрана частина. Ви також можете використовувати стрілку зсуву ліворуч.
  3. Потім натисніть C->(натисніть shift, якщо клавіша >знаходиться над клавішею клавіатури), поки не буде вибрано більше одного елемента.

* Важливо вибрати назад, або перший вибір поставить курсор у неправильне положення.

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