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 an active region, add brackets around region. • If WrapMethod is `line', wrap around line. • If WrapMethod is `block', wrap around block. • 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' Version: 2017-01-17 2021-08-12" (if (region-active-p) (progn (let ( (xp1 (region-beginning)) (xp2 (region-end))) (goto-char xp2) (insert RBracket) (goto-char xp1) (insert LBracket) (goto-char (+ xp2 2)))) (let (xp1 xp2) (cond ((eq WrapMethod 'line) (setq xp1 (line-beginning-position) xp2 (line-end-position)) (goto-char xp2) (insert RBracket) (goto-char xp1) (insert LBracket) (goto-char (+ xp2 (length LBracket)))) ((eq WrapMethod 'block) (save-excursion (let ((xbds (xah-get-bounds-of-block-or-region))) (setq xp1 (car xbds) xp2 (cdr xbds))) (goto-char xp2) (insert RBracket) (goto-char xp1) (insert LBracket) (goto-char (+ xp2 (length LBracket))))) ( ; do line. line must contain space (and (eq (point) (line-beginning-position)) ;; (string-match " " (buffer-substring-no-properties (line-beginning-position) (line-end-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 (string-equal major-mode "xah-elisp-mode") (string-equal major-mode "emacs-lisp-mode") (string-equal major-mode "lisp-mode") (string-equal major-mode "lisp-interaction-mode") (string-equal major-mode "common-lisp-mode") (string-equal major-mode "clojure-mode") (string-equal major-mode "xah-clojure-mode") (string-equal major-mode "scheme-mode")))) (progn (setq xp1 (point) xp2 (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 xp1 (point)) (skip-chars-forward "-_[:alnum:]") (setq xp2 (point)) (goto-char xp2) (insert RBracket) (goto-char xp1) (insert LBracket) (goto-char (+ xp2 (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-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-ascii-double-quote () (interactive) (xah-insert-bracket-pair "\"" "\"") ) (defun xah-insert-ascii-single-quote () (interactive) (xah-insert-bracket-pair "'" "'") ) (defun xah-insert-emacs-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 "〔" "〕" ) )
requires package Emacs: xah-get-thing.el 📦
〔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 📦