Emacs: Insert Brackets by Pair 💠

By Xah Lee. Date: . Last updated: .

This page shows a command to insert bracket pair, better than the emacs builtin electric-pair-mode .

Problems of electric-pair-mode

Advantages of xah-insert-bracket-pair

Commands to Insert Brackets by Pair

Put this in your Emacs Init File:

(defun xah-insert-bracket-pair (LBracket RBracket &optional WrapMethod)
  "Insert brackets around selection, word, at point, and maybe move cursor in between.

 LBracket and RBracket are strings. WrapMethod must be either `line' or `block'. `block' means between empty lines.

• If there is a active region, wrap around region.
Else
• If WrapMethod is `line', wrap around line.
• If WrapMethod is `block', wrap around block.
Else
• If cursor is at beginning of line and its not empty line and contain at least 1 space, wrap around the line.
• If cursor is at end of a word or buffer, one of the following will happen:
 xyz▮ → xyz(▮)
 xyz▮ → (xyz▮)       if in one of the lisp modes.
• wrap brackets around word if any. e.g. xy▮z → (xyz▮). Or just (▮)

URL `http://xahlee.info/emacs/emacs/elisp_insert_brackets_by_pair.html'
Created: 2017-01-17
Version: 2025-03-25"
  (if (region-active-p)
      (progn
        (let ((xbeg (region-beginning)) (xend (region-end)))
          (goto-char xend) (insert RBracket)
          (goto-char xbeg) (insert LBracket)
          (goto-char (+ xend 2))))
    (let (xbeg xend)
      (cond
       ((eq WrapMethod 'line)
        (setq xbeg (line-beginning-position) xend (line-end-position))
        (goto-char xend)
        (insert RBracket)
        (goto-char xbeg)
        (insert LBracket)
        (goto-char (+ xend (length LBracket))))
       ((eq WrapMethod 'block)
        (save-excursion
          (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
          (goto-char xend)
          (insert RBracket)
          (goto-char xbeg)
          (insert LBracket)
          (goto-char (+ xend (length LBracket)))))
       ( ; do line. line must contain space
        (and
         (eq (point) (line-beginning-position))
         (not (eq (line-beginning-position) (line-end-position))))
        (insert LBracket)
        (end-of-line)
        (insert  RBracket))
       ((and
         (or ; cursor is at end of word or buffer. i.e. xyz▮
          (looking-at "[^-_[:alnum:]]")
          (eq (point) (point-max)))
         (not (or
               (eq major-mode 'xah-elisp-mode)
               (eq major-mode 'emacs-lisp-mode)
               (eq major-mode 'lisp-mode)
               (eq major-mode 'lisp-interaction-mode)
               (eq major-mode 'common-lisp-mode)
               (eq major-mode 'clojure-mode)
               (eq major-mode 'xah-clojure-mode)
               (eq major-mode 'scheme-mode))))
        (progn
          (setq xbeg (point) xend (point))
          (insert LBracket RBracket)
          (search-backward RBracket)))
       (t (progn
            ;; wrap around “word”. basically, want all alphanumeric, plus hyphen and underscore, but don't want space or punctuations. Also want chinese chars
            ;; 我有一帘幽梦,不知与谁能共。多少秘密在其中,欲诉无人能懂。
            (skip-chars-backward "-_[:alnum:]")
            (setq xbeg (point))
            (skip-chars-forward "-_[:alnum:]")
            (setq xend (point))
            (goto-char xend)
            (insert RBracket)
            (goto-char xbeg)
            (insert LBracket)
            (goto-char (+ xend (length LBracket)))))))))
(defun xah-insert-paren () (interactive) (xah-insert-bracket-pair "(" ")"))
(defun xah-insert-square-bracket () (interactive) (xah-insert-bracket-pair "[" "]"))
(defun xah-insert-brace () (interactive) (xah-insert-bracket-pair "{" "}"))

(defun xah-insert-ascii-double-quote () (interactive) (xah-insert-bracket-pair "\"" "\""))
(defun xah-insert-ascii-single-quote () (interactive) (xah-insert-bracket-pair "'" "'"))
(defun xah-insert-ascii-angle-bracket () (interactive) (xah-insert-bracket-pair "<" ">"))

(defun xah-insert-emacs-quote () (interactive) (xah-insert-bracket-pair "`" "'"))
(defun xah-insert-markdown-quote () (interactive) (xah-insert-bracket-pair "`" "`"))
(defun xah-insert-markdown-triple-quote () (interactive) (xah-insert-bracket-pair "```\n" "\n```"))

(defun xah-insert-double-curly-quote“” () (interactive) (xah-insert-bracket-pair "“" "”"))
(defun xah-insert-curly-single-quote‘’ () (interactive) (xah-insert-bracket-pair "‘" "’"))
(defun xah-insert-single-angle-quote‹› () (interactive) (xah-insert-bracket-pair "‹" "›"))
(defun xah-insert-double-angle-quote«» () (interactive) (xah-insert-bracket-pair "«" "»"))

(defun xah-insert-corner-bracket「」 () (interactive) (xah-insert-bracket-pair "「" "」"))
(defun xah-insert-white-corner-bracket『』 () (interactive) (xah-insert-bracket-pair "『" "』"))
(defun xah-insert-angle-bracket〈〉 () (interactive) (xah-insert-bracket-pair "〈" "〉"))
(defun xah-insert-double-angle-bracket《》 () (interactive) (xah-insert-bracket-pair "《" "》"))
(defun xah-insert-white-lenticular-bracket〖〗 () (interactive) (xah-insert-bracket-pair "〖" "〗"))
(defun xah-insert-black-lenticular-bracket【】 () (interactive) (xah-insert-bracket-pair "【" "】"))
(defun xah-insert-tortoise-shell-bracket〔〕 () (interactive) (xah-insert-bracket-pair "〔" "〕"))
(defun xah-insert-deco-angle-bracket❮❯ () (interactive) (xah-insert-bracket-pair "❮" "❯"))
(defun xah-insert-deco-angle-fat-bracket❰❱ () (interactive) (xah-insert-bracket-pair "❰" "❱"))

〔see Unicode: Brackets, Quotes 「」【】《》

Setting Up Keys to Insert Brackets by Pair

Now you can set any key to call your commands.

(global-set-key (kbd "<f8> 7") 'xah-insert-brace) ; {}
(global-set-key (kbd "<f8> 8") 'xah-insert-paren) ; ()
(global-set-key (kbd "<f8> 9") 'xah-insert-square-bracket) ; []

or

(global-set-key (kbd "M-7") 'xah-insert-brace) ; {}
(global-set-key (kbd "M-8") 'xah-insert-paren) ; ()
(global-set-key (kbd "M-9") 'xah-insert-square-bracket) ; []

〔see Emacs Keys: Define Key

Emacs, Work with Brackets