1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
;; help out a TextMate junkie
(defun wrap-region (left right beg end)
"Wrap the region in arbitrary text, LEFT goes to the left and RIGHT goes to the right."
(interactive)
(save-excursion
(goto-char beg)
(insert left)
(goto-char (+ end (length left)))
(insert right)))
(defmacro wrap-region-with-function (left right)
"Returns a function which, when called, will interactively `wrap-region-or-insert' using LEFT and RIGHT."
`(lambda () (interactive)
(wrap-region-or-insert ,left ,right)))
(defun wrap-region-with-tag-or-insert ()
(interactive)
(if (and mark-active transient-mark-mode)
(call-interactively 'wrap-region-with-tag)
(insert "<")))
(defun wrap-region-with-tag (tag beg end)
"Wrap the region in the given HTML/XML tag using `wrap-region'. If any
attributes are specified then they are only included in the opening tag."
(interactive "*sTag (including attributes): \nr")
(let* ((elems (split-string tag " "))
(tag-name (car elems))
(right (concat "</" tag-name ">")))
(if (= 1 (length elems))
(wrap-region (concat "<" tag-name ">") right beg end)
(wrap-region (concat "<" tag ">") right beg end))))
(defun wrap-region-or-insert (left right)
"Wrap the region with `wrap-region' if an active region is marked, otherwise insert LEFT at point."
(interactive)
(if (and mark-active transient-mark-mode)
(wrap-region left right (region-beginning) (region-end))
(insert left)))
(global-set-key "'" (wrap-region-with-function "'" "'"))
(global-set-key "\"" (wrap-region-with-function "\"" "\""))
(global-set-key "`" (wrap-region-with-function "`" "`"))
(global-set-key "(" (wrap-region-with-function "(" ")"))
(global-set-key "[" (wrap-region-with-function "[" "]"))
(global-set-key "{" (wrap-region-with-function "{" "}"))
(global-set-key "<" 'wrap-region-with-tag-or-insert) ;; I opted not to have a wrap-with-angle-brackets |