Emacs: Insert Brackets by Pair 💠
This page shows a command to insert bracket pair, better than the emacs builtin electric-pair-mode .
Problems of electric-pair-mode
- Some brackets are not paired in some major mode, unpredictable behavior. (more precisely, it depends on the value of Syntax Table) . (e.g. In emacs-lisp-mode, it does not close curly brackets {}. In js-mode it pairs single quote.)
- The keys to insert brackets is typed by your stretched pinky. Not ergonomic.
Advantages of xah-insert-bracket-pair
- Wrap brackets around current word (if cursor is on a word), or text selection, else just insert a pair and place cursor in between.
- Behavior is same and predictable anywhere. (not dependent on syntax table.)
- Convient shortcuts keys on home row, or any key you chose.
- Inserts 10 other Unicode brackets and quotes.
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
- Emacs Init: Highlight Brackets
- Emacs Init: Auto Insert Closing Bracket (electric-pair-mode)
- Emacs: Insert Brackets by Pair 💠
- Emacs: Delete Brackets by Pair 💠
- Emacs: Move Cursor to Bracket 💠
- Emacs: Jump to Matching Bracket 💠
- Emacs: Change Brackets 💠
- Emacs: Navigate Lisp Code as Tree
- Emacs: Select Text Between Quotes 💠
- Emacs: Xah Elisp Mode 📦