Свернуть выделение в Open / Close Tag, как TextMate?

В TextMate можно использовать ctrl-shift-w для переноса текста в теге Open / Close и ctrl-shift-cmd-w для переноса каждой строки в области в тегах Open / Close. Как я могу реализовать эту же функциональность в Emacs, используя emacs lisp?

Emacs

становится

<Р> Emacs </ р>

А также ...

Emacs
TextMate
VI

становится

<Li> Emacs </ li>
<Li> TextMate </ li>
<Li> VI </ li>
13.10.2009 04:26:03
4 ОТВЕТА
РЕШЕНИЕ

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

Эта процедура предложит вам использовать тег и должна пометить каждую строку в регионе тегом open / close этого типа:

(defun my-tag-lines (b e tag)
  "'tag' every line in the region with a tag"
  (interactive "r\nMTag for line: ")
  (save-restriction
    (narrow-to-region b e)
    (save-excursion
      (goto-char (point-min))
      (while (< (point) (point-max))
        (beginning-of-line)
        (insert (format "<%s>" tag))
        (end-of-line)
        (insert (format "</%s>" tag))
        (forward-line 1)))))

* Примечание: * Если вы хотите, tagчтобы всегда было li, то удалите аргумент тега, удалите текст \nMTag for line:из вызова в интерактив и обновите вызовы вставки, чтобы просто вставить, "<li\>"как вы ожидаете.

7
23.05.2017 10:31:13

yasnippet является особенно хорошей реализацией синтаксиса фрагмента Textmate для Emacs. При этом вы можете импортировать все фрагменты Textmate. Если вы установите его тогда, этот фрагмент, который я написал, должен делать то, что вы хотите:

(defun wrap-region-or-point-with-html-tag (start end)
  "Wraps the selected text or the point with a tag"
  (interactive "r")
  (let (string)
    (if mark-active 
        (list (setq string (buffer-substring start end))
          (delete-region start end)))
    (yas/expand-snippet (point)
                        (point)
                        (concat "<${1:p}>" string "$0</${1:$(replace-regexp-in-string \" .*\" \"\" text)}>"))))

(global-set-key (kbd "C-W") 'wrap-region-or-point-with-html-tag)

РЕДАКТИРОВАТЬ: (Хорошо, это моя последняя попытка исправить это. Это точно так же, как версия Textmate. Он даже игнорирует символы после пробела в конце тега)

Извините, я неправильно понял ваш вопрос. Эта функция должна редактировать каждую строку в регионе.

(defun wrap-lines-in-region-with-html-tag (start end)
  "Wraps the selected text or the point with a tag"
  (interactive "r")
  (let (string)
    (if mark-active 
        (list (setq string (buffer-substring start end))
              (delete-region start end)))
    (yas/expand-snippet
     (replace-regexp-in-string "\\(<$1>\\).*\\'" "<${1:p}>"
      (mapconcat
       (lambda (line) (format "%s" line))
       (mapcar
        (lambda (match) (concat "<$1>" match "</${1:$(replace-regexp-in-string \" .*\" \"\" text)}>"))
        (split-string string "[\r\n]")) "\n") t nil 1) (point) (point))))
3
19.10.2009 11:00:18

Для sgml-modeдеративаций отметьте регион для тегирования, введите M-x sgml-tagи введите имя тега, которое вы хотите использовать (нажмите, TABчтобы получить список доступных элементов HTML). Хотя этот метод не позволяет пометить каждую строку в регионе, вы можете обойти это, записав макрос клавиатуры.

5
13.10.2009 13:33:53

Этот вариант ответа Трея также будет правильно содержать отступ HTML.

(defun wrap-lines-region-html (b e tag) "'tag' every line in the region with a tag" (interactive "r\nMTag for line: ") (setq p (point-marker)) (save-excursion (goto-char b) (while (< (point) p) (beginning-of-line) (indent-according-to-mode) (insert (format "<%s>" tag)) (end-of-line) (insert (format "</%s>" tag)) (forward-line 1))))

0
2.11.2014 02:45:43