HomeMathComputingArtsWordsLiteratureMusictwitter facebook webfeed

Emacs Lisp Multi-Pair Find & Replace Applications

Advertise Here For Profit

Xah Lee, 2011-02-20, 2011-04-01

This article shows several examples of customized find & replace applications in emacs lisp. If you don't know elisp, first take a look at Emacs Lisp Basics.

CSS Compressor

Multi-Pair Find & Replace is useful in many situations. For example, you know how webmasters often need to compact javascript or CSS code, so the file size becomes smaller and decrease page load time? There are many libraries and tools to do that for js and css. (just web search for “css compactor” or “javascript compactor”) With emacs, you can have a lisp function that does a simple code compacting by just find replace. For example, here's my CSS compactor:

(defun compact-css-region ()
  "Remove unnecessary whitespaces of CSS source code in region.
CSS is Cascading Style Sheet.
WARNING: not bullet proof. Only does a simple compression by find replace."
  (interactive)
(let (mystr p1 p2)
(setq p1 (region-beginning))
(setq p2 (region-end))
(setq mystr (buffer-substring p1 p2))
(setq mystr (replace-regexp-pairs-in-string mystr '(["  +" " "])))
(setq mystr (replace-pairs-in-string mystr
'(
["\n" ""]
[" /* " "/*"]
[" */ " "*/"]
[" {" "{"]
["{ " "{"]
["; " ";"]
[": " ":"]

[";}" "}"]
["}" "}\n"]
)))

(delete-region p1 p2)
(insert mystr)
)
)

With the above, you can just press one button to compact your code in current buffer. You can easily modify the code so it does un-compact, or works on whole buffer instead of text selection, or output to a new file.

The code above uses a elisp library 〔xfrp_find_replace_pairs.el〕 so the find/replace pairs are more compact and readable. However, it is not necessary. You can just use the “while” loop with “search-forward-regexp” like before.

See: Emacs Lisp: Multi-Pair String Replacement: xfrp_find_replace_pairs.el.

More Examples

Almost all of the following i use daily multiple times in the past 3 years.

Space, Hyphen, Underscore Cycle

(defun space2underscore-region (start end)
  "Replace space by underscore in region."
  (interactive "r")
(replace-pairs-region start end '([" " "_"])))
(defun underscore2space-region (start end)
  "Replace underscore by space in region."
  (interactive "r")
(replace-pairs-region start end '(["_" " "])))

For better command, see: Emacs Lisp: Cycle Replace Space Hyphen Underscore.

Escape/UnEscape Backslash

These are very useful when you code elisp for text processing. For example, i often have a text copied from some html that i need to search for in my elisp code. After pasting the text, i need to quote them. (elisp does not support heredoc.)

(defun escape-quotes-region (start end)
  "Replace \" by \\\" in region."
  (interactive "r")
  (replace-pairs-region start end '(["\"" "\\\""])))
(defun unescape-quotes-region (start end)
  "Replace \\\" by \" in region."
  (interactive "r")
  (replace-pairs-region start end '(["\\\"" "\""])))

Unicode Replacement

Useful if you work with math a lot.

(defun replace-mathematica-symbols-region (start end)
  "Replace Mathematica's special char encoding to unicode of the same semantics.
For example:
 \\=\\[Infinity] ⇒ ∞
 \\=\\[Equal] ⇒ =="
  (interactive "r")
  (replace-pairs-region start end '(
 ["\\[Infinity]" "∞"]
 ["\\[Equal]" "=="])))
(defun replace-greek-region (start end)
  "Replace math symbols. e.g. alpha to α."
  (interactive "r")
(replace-pairs-region start end '(
["alpha" "α"]
["beta" "β"]
["gamma" "γ"]
["theta" "θ"]
["lambda" "λ"]
["delta" "δ"]
["epsilon" "ε"]
["omega" "ω"]
["Pi" "π"])))

See:

Curly Quote Fixes

(defun replace-curly-apostrophe-region (start end)
  "Replace some single curly quotes ‘ or ’ to '."
  (interactive "r")
(replace-pairs-region start end '(
["‘tis" "'tis"]
["’s" "'s"]
["’d" "'d"]
["n’t" "n't"]
["’ve" "'ve"]
["’ll" "'ll"]
["’m" "'m"]
["’re" "'re"]
["s’ " "s' "])))
(defun replace-straight-quotes-region (p1 p2)
  "Replace straight double quotes to curly ones
Also replace “--” by “—”."
  (interactive "r")
  (let (quoteReplaceMap)
    ;; a map that helps converting straight quotes to double quotes in texts
    ;; (e.g. novels). Note: order is important since this is huristic.
    (setq quoteReplaceMap
          '(
["--" " — "]
["  —  " " — "]
[">\"" ">“"]
["(\"" "(“"]
[" \"" " “"]
["\" " "” "]
["\"," "”,"]
["\"." "”."]
["\"?" "”?"]
["\";" "”;"]
["\":" "”:"]
["\")" "”)"]
["\"]" "”]"]
[".\"" ".”"]
[",\"" ",”"]
["!\"" "!”"]
["?\"" "?”"]
;; ";
["\n\"" "\n“"]
[">\'" ">‘"]
[" \'" " ‘"]
["\' " "’ "]
["\'," "’,"]
[".\'" ".’"]
["!\'" "!’"]
["?\'" "?’"]
["(\'" "(‘"]
["\')" "’)"]
["\']" "’]"]
[" ‘em" " 'em"]))

    (replace-pairs-region p1 p2 quoteReplaceMap)))

Make HTML Table

Another different use, but essentially same technique of find & replace, is to turn a plain text table into a html table. See: Emacs Lisp: How to Write a make-html-table Command.

Assign a Hotkey or Alias

You can assign a hotkey for them (see: Emacs: How to Define Keyboard Shortcuts.) Hotkey lets you call a command by 1 single button press. But one problem is that, when you have tens of personal commands, you may not remember the key for a command you defined a few months ago. One solution is using alias.

You can define a alias for any emacs commands. Example:

(defalias 'dj 'dired-jump)
(defalias 'g 'grep)
(defalias 'gf 'grep-find)
(defalias 'fd 'find-dired)
(defalias 'ntr 'narrow-to-region)

Emacs is fantastic!

blog comments powered by Disqus