Как выбрать несмежные регионы в Emacs?

31

Предположим, что я уже выделил некоторый текст в текущем буфере. Можно ли выбрать другой фрагмент текста, сохранив предыдущий выбор (и т. Д.)?

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

paragraph 1 ...

paragraph 2 ...

paragraph 3 ...

paragraph 4 ...

paragraph 5 ...

Я хотел бы удалить некоторые пункты (например, 2, 4 и 6) и вставить их перед пунктом 1.

название
источник
1
Там вторичный выбор .
Васамаса
2
Есть пакет multiselect: skamphausen.de/cgi-bin/ska/multiselect Это выглядит как быстрый взлом.
Тобиас
В зависимости от размера того, что вы выбираете и почему, multiple-cursorsможет дать вам решение.
Джордон Биондо
@wasamasa Я следовал инструкциям, приведенным в ссылке, которую вы предоставили. После первого выбора я выбрал второй регион, удерживая мета-ключ. Он был выбран, но есть две проблемы: (1) второй выбор, кажется, не реальный выбор, поскольку копирование или удаление не работают. (2) таким способом невозможно выбрать третий выбор.
Имя
1
В Emacs Wiki есть хороший раздел о вторичном выборе . Различные улучшения делают его более удобным, например, с клавиатуры.
Дрю

Ответы:

43

Вы можете использовать append-next-kill(привязано к C-M-wпо умолчанию) для накопления текста, который вы хотите вставить выше paragraph 1:

  1. Убей paragraph 2как обычно.

  2. Отметьте paragraph 4и нажмите, C-M-wпрежде чем убить его. Повторите этот шаг для всех абзацев, которые вы хотели бы переместить раньше paragraph 1.

Когда вы закончите, вы можете восстановить накопленный текст раньше paragraph 1.

itsjeyd
источник
5
Даже с базовыми вещами всегда есть что-то новое для изучения! Это очень полезно, так как я обычно трачу много нажатий клавиш, путешествуя по кольцу уничтожения, когда мне нужно это сделать. Жаль, что я не мог бы поднять это еще немного ...
Значимое имя пользователя
9

Вы можете использовать регистры в сочетании с кольцом меток. Нажмите текущие отметки с помощью C-<SPC> C-<SPC>, восстановите их позже с помощью C-u C-<SPC>или сохраните их в регистре, скажем b, с помощью C-x r <SPC> b, и вернитесь позже с помощью C-x r j b.

Теперь отметьте другой регион. C-u C-x r s aскопирует отмеченный регион для регистрации aи удалит текст. Затем отметьте следующий регион и C-u C-x r + aдобавьте другой выбор в этот регистр aи удалите его.

Затем вы можете вставить содержимое с помощью C-x r i a.

Смотрите раздел "Сохранение текста в регистрах" руководства Emacs.

Эндрю Суонн
источник
5

Новая поддержка прямоугольной области в Emacs-24.4 фактически представила (большую часть) инфраструктуру, необходимую для этой функциональности [в конце концов, прямоугольная область является несмежной областью].

Таким образом, теперь должна быть возможность реализовать пакет «split-region», который предоставляет только те функции, которые вы запрашиваете.

Следует признать, что многие команды Emacs до сих пор не адаптированы для использования новой инфраструктуры (например, такие команды, как upcase-region или undo-in-region, query-replace, ...) и, следовательно, еще не работают должным образом с прямоугольниками (поэтому они также не будут работать должным образом в «разделенной области»), но это ошибки, которые, мы надеемся, со временем исправятся.

Стефан
источник
4

Установите browse-kill-ring.el

копировать и убивать все области интересов.

Добрался до точки, где должна начаться повторная вставка

M-x browse-kill-ring RET откроет буфер и поместит в него курсор.

Типа nпутешествовать кусками.

RET там будет вставлен кусок в точку в оригинальный / другой буфер.

Андреас Рёлер
источник
3

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

Это прекрасно работает, например, в сочетании с режимом нескольких курсоров : поскольку строки, выбранные вами для отображения в буфере Occur, отображаются непрерывно, независимо от того, как далеко они находятся в исходном буфере, вы можете пометить их все или подмножество, а затем активировать mc/edit-linesи редактировать их все сразу. (Да, я знаю, что множественные курсоры могут делать все это самостоятельно mc/mark-all-like-this, но приятно иметь варианты.)

Любая другая операция редактирования, которую было бы легче выполнить, если бы вы видели только те строки, над которыми вы хотели работать, например, настройка сложного поиска и замены регулярных выражений или макрос, который должен выполняться по очереди в каждой строке буфера, также может быть сделано таким образом.

dodgethesteamroller
источник
3

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

Emacs теперь имеет то, что он называет несмежным регионом , и это тот тип выбора, о котором вы спрашиваете. Vanilla Emacs не предоставляет какого-либо специального способа создания несмежной области, кроме случаев, когда это прямоугольник . Но библиотека Zones делает.

Библиотечные зоны позволяют вам определять несколько зон в буфере. Список зона является несмежной областью . Вы также можете думать о нем как о нескольких регионах, в зависимости от того, как вы хотите его использовать. Вы можете иметь несколько списков зон, определенных в любое время, каждый из которых назначен разной переменной зоны, и вы можете переключаться между ними.

Если вы также используете библиотеку Bookmark +, то вы можете постоянно сохранять списки зон и восстанавливать их в последующих сеансах Emacs. Bookmark + также позволяет назначать произвольные теги для закладки. Это означает, что вы можете пометить список зон.

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

Есть несколько способов создать зону. Одним из самых простых является использование C-x n a: он определяет зону из активной области и добавляет ее в текущий набор зон. ( C-x n n( narrow-to-region) также делает это, в дополнение к сужению.)

Вот некоторые вещи, которые вы можете сделать с помощью набора (списка) зон:

  • Сортировать их.
  • Объединить (объединить) смежные или перекрывающиеся зоны (что включает их сортировку).
  • Пересечь их.
  • Сузьте буфер до зоны в списке. Цикл среди сужений. Смотрите несколько сужений .
  • Выберите зону в списке в качестве активной области. Цикл среди регионов.
  • Поиск их (они автоматически объединяются в первую очередь). Для этого вам понадобится библиотека Isearch + .
  • Запросить-заменить их.
  • Выделите и не выделите их. (Для этого вам нужна библиотека Highlight или библиотека facemenu+.el.

Смотрите также Narrow Indirect , который позволяет создавать косвенные буферы, которые являются клонами данного буфера и сужены к различным его частям.

Нарисовался
источник
2

Другой вариант: перенос абзацев

Для полноты картины вы можете добиться переупорядочения абзацев (последовательно) с отмеченными областями и M-0 M-x transpose-paragraph(нулевой аргумент заставляет tra-parпоменять параграфы, в которых находятся точка и метка, т.е. область начинается и заканчивается)!

Кстати, это работает для всех transpose-.*команд (-words, -sexp, -sentences, ...) и очень удобно во многих ситуациях.

Dieter.Wilhelm
источник
2

Другой способ - использовать пакет objed (я автор). Вы можете пометить любой текстовый объект так, mчтобы точка автоматически перемещалась к следующему объекту текущего типа. Снимите пометку с любого объекта, перейдя к нему, и снова нажмите m. Вот пример скриншота (показывает разметку линий, но работает и для других объектов, таких как абзацы, определения функций ... также):

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

clemera
источник
Когда я пытаюсь установить этот пакет от Melpa, я получаю сообщение об ошибке package-install-from-archive: http://melpa.milkbox.net/packages/objed-20181201.1346.tar: Not found.
Имя
@ Имя Это звучит как необходимость обновить список пакетов. Попробуй M-x package-refresh-contentsи тогда M-x package-install.
Клемера
@ Name Это работает сейчас? Дайте мне знать, если у вас есть дополнительные вопросы.
Клемера
Я смог установить пакет. Кажется, работает хорошо, я не проверял все его функции. Спасибо.
Имя