Wrap text in custom characters

I posted recently about wrapping text in an org-mode block, and decided I wanted a quick way to wrap text in other formatting strings. I quickly came across the excellent wrap-region package which does just this.

For example, with a quick bit of setup you can highlight some words like foo bar in an org-mode buffer and hit * which wraps the words with that character to give *foo bar*, rendering them in boldface. It supports various parentheses out of the box, so hitting ( will wrap the highlighted region in ().

This works really well with expand-region to quickly highlight a word or sentence before wrapping it.

You can install the wrap-region package through MELPA. I added the following lines to my emacs config file to configure it

;; wrap-region
(use-package wrap-region
  :ensure t
  :config
  (wrap-region-add-wrappers
   '(("*" "*" nil org-mode)
     ("~" "~" nil org-mode)
     ("/" "/" nil org-mode)
     ("=" "=" nil org-mode)
     ("_" "_" nil org-mode)
     ("$" "$" nil (org-mode latex-mode))))
  (add-hook 'org-mode-hook 'wrap-region-mode)
  (add-hook 'latex-mode-hook 'wrap-region-mode))

This sets up the common org-mode delimiters and adds $ delimiters for org-mode and latex-mode. I then use the hooks so that wrap-region is only active in org-mode and latex-mode buffers.

Note that in this configuration I have made use of use-package which is a nice way of organising your installed packages and their configuration. I’ll write more about that in due course, but for now, if you want to use the code above in your emacs config file then you need to install use-package and add

(require 'use-package)

to the top of your config file.

Update

I realised that configuration above doesn’t work perfectly with expand-region, since hitting = to wrap a region in = instead expands the region by another level. Happily, wrap-region provides a nice way to work around this. In the code below I set + as the key to wrap a region in = characters, which is convenient as it is on the same key. Usually wrapping a string in + symbols in org-mode gives a strikethrough, but I rarely use this so I’m happy to do that manually when needed.

;; wrap-region
(use-package wrap-region
  :ensure t
  :config
  (wrap-region-add-wrappers
   '(("*" "*" nil org-mode)
     ("~" "~" nil org-mode)
     ("/" "/" nil org-mode)
     ("=" "=" "+" org-mode)
     ("_" "_" nil org-mode)
     ("$" "$" nil (org-mode latex-mode))))
  (add-hook 'org-mode-hook 'wrap-region-mode)
  (add-hook 'latex-mode-hook 'wrap-region-mode))