При использовании Emacs мне обычно нужно выполнять несколько операций над одним и тем же регионом (часто довольно большим, но не четко определенным объектом, таким как "весь раздел", "весь абзац"). В настоящее время я должен вручную пометить регион, выполнить первую операцию, затем вернуться назад и повторно отметить регион, а также выполнить вторую операцию и повторить ... Это очень громоздко. Интересно, есть ли какой-нибудь ярлык, чтобы пометить ранее отмеченный регион? Или каким-то образом сохранить область отмеченной, пока я не скажу Emacs снять метку.
7 ответов
Если регион только что был помечен (что Emacs называет "деактивированным"), Cx Cx заметит (или "повторно активирует") его.
Приведенные ниже фрагменты скрипта свяжут аккорды клавиш F6
, C-F6
, C-S-F6
с маркерами менеджера (против маркера). Маркеры перемещаются, уменьшаются и растут по мере изменения текста вокруг и между ними. Вы можете использовать любые клавиши, которые вы предпочитаете. Поместите код в файл конфигурации ~/.emacs
.
- Сначала установите границы начальной области (точка-точка).
- Затем нажмите
F6
чтобы установить маркеры на границы этого региона. - Делай все, что тебе нужно ...
- Восстановите границы измененной области, нажав
C-F6
.Повторите * "Do ..", как это будет необходимо - Когда вы закончите, используйте
C-S-F6
чтобы очистить маркеры региона.
(global-set-key (kbd "<f6>") 'set-markers-for-region)
(defun set-markers-for-region ()
(interactive)
(make-local-variable 'm1)
(make-local-variable 'm2)
(setq m1 (copy-marker (mark)))
(setq m2 (copy-marker (point))))
(global-set-key (kbd "<C-f6>") 'set-region-from-markers)
(defun set-region-from-markers ()
(interactive)
(set-mark m1)
(goto-char m2))
(global-set-key (kbd "<C-S-f6>") 'unset-region-markers)
(defun unset-region-markers ()
(interactive)
(set-marker m1 nil)
(set-marker m2 nil))
К сожалению, в Emacs нет функции истории региона. Существует функция pop-mark
, которая восстанавливает метку в предыдущую позицию, взятую из переменной mark-ring
, но она не устанавливает точку и, следовательно, бесполезна для восстановления старых областей. Если вы знакомы с Emacs-Lisp , вы можете посоветовать функцию set-mark
с кодом, который поддерживает кольцо региона (аналогично переменной mark-ring
). Тогда вы могли бы реализовать функцию pop-region
которая ведет себя так же, как pop-mark
.
В зависимости от ваших повторных операций, вы можете записать макрос, используя команду «pop-global-mark» для возврата к последней метке в глобальном кольце меток, или вы можете явно сохранить свое место с помощью команды регистра emacs, и затем после 2-й операции вернитесь с помощью команды register. Команда register немного более грубая и несколько нажатий клавиш, но я считаю ее надежной.
Если вы используете библиотеку second-sel.el
вы можете использовать вторичный выбор, чтобы помочь с этим. Вторичный выбор не связан с точкой или меткой, поэтому он остается на месте, даже когда точка перемещается (так что да, в отличие от региона, он может перемещаться за пределы экрана).
С помощью этого предложенного связывания ключей:
(global-set-key (kbd "C-M-y") 'secondary-yank|select|move|swap)
Вы можете сделать следующее:
C-1 C-M-y
чтобы выбрать активную область в качестве вторичного выбора.Делайте все, что вам нужно: передвигаться, выбирать другой текст (менять регион), что угодно.
Если вы хотите вернуть регион туда, где он был, где еще находится вторичный выбор, просто используйте
C-0 C-M-y
.
Это все. Просто C-1 C-M-y
чтобы сделать снимок региона (в качестве вторичного), а затем C-0 C-M-y
чтобы активировать регион, где он был во время моментального снимка.
Вы также можете использовать C-- C-M-y
чтобы поменять местами регион и вторичный выбор. Так, например, если cat
является (активной) областью, а dog
вторичной, то C-- C-M-y
делает cat
вторичной, а dog
- (активной).
Следующее решение имеет следующие преимущества: требуется только одна функция и одна привязка клавиш:
(defun my-reuse-region (unset)
"Enable re-use of regions.
When a region is selected, save its bounds for future use.
Otherwise, activate the saved bounds. With a prefix argument,
unsets any prior saved bounds."
(interactive "P")
(cond
(unset
(makunbound 'my-reusable-mark)
(makunbound 'my-reusable-mark))
((region-active-p)
(when (not (boundp 'my-reusable-mark))
(make-local-variable 'my-reusable-mark))
(when (not (boundp 'my-reusable-point))
(make-local-variable 'my-reusable-point))
(setq my-reusable-mark (copy-marker (mark)))
(setq my-reusable-point (copy-marker (point)))
(message "Region bounds saved for future use."))
(t
(when (and (boundp 'my-reusable-mark)
(boundp 'my-reusable-point))
(set-mark my-reusable-mark)
(goto-char my-reusable-point)))))
(global-set-key (kbd "C-c C-SPC") 'my-reuse-region)
Примечание: я не совсем уверен, что есть вариант использования для вызова функции с аргументом префикса; Я добавил этот код только для того, чтобы быть добросовестным и тщательным.
Обычным рабочим процессом является narrow-to-region
(C-x n n
), а затем выполнение ваших задач в видимой области. Затем widen
(C-x n w
), чтобы снова открыть оставшуюся часть буфера, когда закончите.