Skip to content

Instantly share code, notes, and snippets.

@howardabrams
Last active December 10, 2016 11:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save howardabrams/9934160 to your computer and use it in GitHub Desktop.
Save howardabrams/9934160 to your computer and use it in GitHub Desktop.
Now that we can easily make a region based on "syntactic components" using the `expand-region` command, wrapping a logical block of text with a beginning and ending string really makes sense. This "version" is more Emacs-y in that it `lets` all the variables, and then `setq` them to their proper values. While I'm not pedantic, I don't like such …
(defun surround (start end txt)
"Wraps the specified region (or the current 'symbol / word'
with some textual markers that this function requests from the
user. Opening-type text, like parens and angle-brackets will
insert the matching closing symbol.
This function also supports some org-mode wrappers:
- `#s` wraps the region in a source code block
- `#e` wraps it in an example block
- `#q` wraps it in an quote block"
(interactive "r\nsEnter text to surround: " start end txt)
;; If the region is not active, we use the 'thing-at-point' function
;; to get a "symbol" (often a variable or a single word in text),
;; and use that as our region.
(if (not (region-active-p))
(let ((new-region (bounds-of-thing-at-point 'symbol)))
(setq start (car new-region))
(setq end (cdr new-region))))
(let (s-table s-pair front-text back-text)
;; We create a table of "odd balls" where the front and the end are
;; not the same string.
(setq s-table '(("#e" ("#+BEGIN_EXAMPLE\n" "\n#+END_EXAMPLE") )
("#s" ("#+BEGIN_SRC \n" "\n#+END_SRC") )
("#q" ("#+BEGIN_QUOTE\n" "\n#+END_QUOTE"))
("<" ("<" ">"))
("(" ("(" ")"))
("{" ("{" "}"))
("[" ("[" "]"))))
;; Why yes, we'll add more
(setq s-pair (assoc txt s-table))
(if s-pair
(progn (setq front-text (car s-pair))
(setq back-text (cadr s-pair)))
;; If txt doesn't match a table entry, then the pair will just be
;; the text for both the front and the back...
(setq front-text txt)
(setq back-text txt))
(save-excursion
(narrow-to-region start end)
(goto-char (point-min))
(insert (car s-pair))
(goto-char (point-max))
(insert (cadr s-pair))
(widen))))
(global-set-key (kbd "C-+") 'surround)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment