Как обернуть данный текст вокруг региона

11

У меня часто бывает ситуация, когда мне нужно применить текст вокруг региона. Для HTML и простых случаев уже есть библиотеки для этого. Но как насчет общего случая? Я хотел бы спросить, что я собираюсь вставить начало и конец региона.

nperson325681
источник
Вы хотите использовать его для вставки произвольного контента один раз или нескольких пар много раз? В последнем случае библиотеки, такие как smartparens, могут оказаться полезными, и они могут быть расширены с помощью пользовательских пар. Например, вы можете добавить пару <?php... ?>, а затем, когда вы выбираете регион и тип <?php(или связывание клавиш), обернуть его в пару. Но на самом деле нет простого способа использовать эти библиотеки, если у вас много пар «один выстрел».
Т. Веррон
@ Т. Веррон: Я знаю, что они существуют. Но для тех моментов, когда есть уникальная необходимость пройти через код и пометить материал,
подойдет

Ответы:

6

Я погуглил и нашел этот пост Джона Д. Кука . Он демонстрирует, как создать простую интерактивную функцию, чтобы легко получить теги HTML / XML по всему региону. Из этого я изменил функцию, чтобы спросить дважды.

(defun tag-word-or-region (text-begin text-end)
  "Surround current word or region with given text."
  (interactive "sStart tag: \nsEnd tag: ")
  (let (pos1 pos2 bds)
    (if (and transient-mark-mode mark-active)
        (progn
          (goto-char (region-end))
          (insert text-end)
          (goto-char (region-beginning))
          (insert text-begin))
      (progn
        (setq bds (bounds-of-thing-at-point 'symbol))
        (goto-char (cdr bds))
        (insert text-end)
        (goto-char (car bds))
        (insert text-begin)))))

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

(defun tag-php ()
  (interactive)
  (tag-word-or-region "<?php " "?>"))
nperson325681
источник
Кстати, способ, которым это обрабатывает некоторые граничные случаи, не оптимален; поиск начала может иногда заканчиваться неудачей и оставлять оба тега в конце. Может быть evil, я использую то, что мешает здесь. Возможно, функция типа interactive "r" работала более надежно?
nperson325681
4

Я бы предложил другой подход. Когда есть регион, по определению pointдолжен быть в начале (или конце) региона, и markбудет в конце (или начале). Это означает, что вы можете ввести текст, который вы хотите в точке, а затем использовать exchange-point-and-mark, то есть C-x C-x, чтобы перейти к другому концу области. Введите вторую половину вашей обертки, и все готово.

Вы не получите явного запроса на ввод текста, но я не могу представить, что был бы способ сделать то же самое с меньшими усилиями.

Тайлер
источник
Если начальный и конечный текст один и тот же, мне интересно, можно ли что-то multiple-cursorsнастроить, чтобы вставить текст одновременно в начало и конец активной области.
glucas
Это похоже на ручной способ, которым пользователи меньших редакторов вынуждены все равно заниматься. Во всяком случае, я прочитал использование макросов как подтекст из вашего ответа, должен сказать. Мне нравится твой стиль
nperson325681
1
@progo - Спасибо :) Это звучит как более ручной подход, но на самом деле он использует меньше нажатий клавиш, чем ваша альтернатива. При таком подходе, кроме переноса текста, вам нужно всего лишь C-x C-x. С вашим ответом вам нужно вызвать вашу функцию ( C-c something), и вам также нужно нажимать returnпосле каждой записи. Поэтому независимо от того, что вы делаете, у вас есть еще два нажатия клавиш. Тем не менее, это не поможет, если вы хотите что-то позвонить от elisp.
Тайлер
3

Просто ради разнообразия:

Другой способ сделать это с некоторым произвольным начальным и конечным текстом было бы использовать replace-regexpна области: матч .+и заменить before \& after, или любой другой текст , который вы хотите использовать для beforeи after.

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

Конечно, если текст, который вы хотите обернуть, может быть выражен как регулярное выражение, тогда вам даже не нужно будет выделять область и выполнять операции с query-replace-regexpбуфером, но, вероятно, текст, который вы хотите обернуть, не такой последовательный.

glucas
источник