Emacs: Change Brackets ๐Ÿ“œ

By Xah Lee. Date: . Last updated: .

Here's command to change brackets in text.

For example, here's what you have:

matrix = [ [3, 99, 'a'], [2, 77, 'a'] ]

You want:

matrix = { {3, 99, 'a'}, {2, 77, 'a'} }

Bracket change is useful when converting data from different languages or formats.

More examples:

put this in your Emacs Init File:

(defun xah-change-bracket-pairs (FromChars ToChars)
  "Change bracket pairs to another type or none.
For example, change all parenthesis () to square brackets [].
Works on current block or selection.

In lisp code, FromChars is a string with at least 2 spaces.
e.g.
paren ( )
french angle โ€น โ€บ
double bracket [[ ]]
etc.
It is split by space, and last 2 items are taken as left and right brackets.

ToChars is similar, with a special value of
none
followed by 2 spaces.
,it means replace by empty string.

URL `http://xahlee.info/emacs/emacs/elisp_change_brackets.html'
Created: 2020-11-01
Version: 2025-03-25"
  (interactive
   (let ((xbrackets
          '(
            "square [ ]"
            "brace { }"
            "paren ( )"
            "less greater than < >"
            "QUOTATION MARK \" \""
            "APOSTROPHE ' '"
            "emacs ` '"
            "GRAVE ACCENT ` `"
            "double square [[ ]]"
            "tilde ~ ~"
            "equal = ="
            "double curly quote โ€œ โ€"
            "single curly quote โ€˜ โ€™"
            "french angle quote โ€น โ€บ"
            "french double angle ยซ ยป"
            "corner ใ€Œ ใ€"
            "white corner ใ€Ž ใ€"
            "lenticular ใ€ ใ€‘"
            "white lenticular ใ€– ใ€—"
            "title angle ใ€ˆ ใ€‰"
            "double angle ใ€Š ใ€‹"
            "tortoise ใ€” ใ€•"
            "white tortoise ใ€˜ ใ€™"
            "white square ใ€š ใ€›"
            "white paren โฆ… โฆ†"
            "white curly bracket โฆƒ โฆ„"
            "pointing angle โŒฉ โŒช"
            "angle with dot โฆ‘ โฆ’"
            "curved angle โงผ โงฝ"
            "math square โŸฆ โŸง"
            "math angle โŸจ โŸฉ"
            "math double angle โŸช โŸซ"
            "math flattened parenthesis โŸฎ โŸฏ"
            "math white tortoise shell โŸฌ โŸญ"
            "heavy single quotation mark ornament โ› โœ"
            "heavy double turned comma quotation mark ornament โ โž"
            "medium parenthesis ornament โจ โฉ"
            "medium flattened parenthesis ornament โช โซ"
            "medium curly ornament โด โต"
            "medium pointing angle ornament โฌ โญ"
            "heavy pointing angle quotation mark ornament โฎ โฏ"
            "heavy pointing angle ornament โฐ โฑ"
            "none  "
            )))
     (let ((completion-ignore-case t))
       (list
        (completing-read "Replace this:" xbrackets nil t nil nil (car xbrackets))
        (completing-read "To:" xbrackets nil t nil nil (car (last xbrackets)))))))
  (let (xbeg xend xleft xright xtoL xtoR)
    (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))))))
    (let ((xsFrom (last (split-string FromChars " ") 2))
          (xsTo (last (split-string ToChars " ") 2)))

      ;; (when (< (length xsFrom) 3)
      ;; (error "cannot find input brackets %s" xsFrom))

      ;; (when (< (length xsTo) 3)
      ;;   (message "replace blacket is empty string")
      ;;   (setq xsTo (list "" "" "")))

      (setq xleft (car xsFrom)  xright (car (cdr xsFrom))
            xtoL (car xsTo) xtoR (car (cdr xsTo)))

      (save-excursion
        (save-restriction
          (narrow-to-region xbeg xend)
          (let ((case-fold-search nil))
            (if (string-equal xleft xright)
                (let ((xx (regexp-quote xleft)))
                  (goto-char (point-min))
                  (while
                      (re-search-forward
                       (format "%s\\([^%s]+?\\)%s" xx xx xx)
                       nil t)
                    (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
                    (replace-match (concat xtoL "\\1" xtoR) t)))
              (progn
                (progn
                  (goto-char (point-min))
                  (while (search-forward xleft nil t)
                    (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
                    (replace-match xtoL t t)))
                (progn
                  (goto-char (point-min))
                  (while (search-forward xright nil t)
                    (overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
                    (replace-match xtoR t t)))))))))))

Emacs, Work with Brackets