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


31

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

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

paragraph 1 ...

paragraph 2 ...

paragraph 3 ...

paragraph 4 ...

paragraph 5 ...

Я хотел бы удалить некоторые пункты (например, 2, 4 и 6) и вставить их перед пунктом 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.


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, но приятно иметь варианты.)

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


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, ...) и очень удобно во многих ситуациях.


2

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

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


Когда я пытаюсь установить этот пакет от 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 Это работает сейчас? Дайте мне знать, если у вас есть дополнительные вопросы.
Клемера

Я смог установить пакет. Кажется, работает хорошо, я не проверял все его функции. Спасибо.
Имя
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.