ErgoEmacsEmacsLispBlogEmacsLispBuy Tutorial
Web Hosting by 1&1

Emacs Lisp Examples ₁

Xah Lee, , …,

This page shows several very simple elisp code. They illustrate the basic programing in elisp, but also, they are very useful themselves.

To see a function's documentation, call describe-functionF1 f】. A variable's documentation is describe-variableF1 v】.

If you do not know the basics of lisp, goto: elisp basics.

Insert Text

This code illustrates how to insert a string, and also position cursor after the insertion.

(defun insert-p-tag ()
  "Insert <p></p> at cursor point."
  (interactive)
  (insert "<p></p>")
  (backward-char 4))

You can use this code to insert your {signature, function template, XML template, headers, footers, …}. (but if you want a systematic set of templates/snippets, better is Emacs Templates with YASnippet.)

wrap-markup-region

This code shows how to place a string at the beginning and end of a region.

(defun wrap-markup-region (start end)
  "Insert a markup <b></b> around a region."
  (interactive "r")
  (save-excursion 
    (goto-char end) (insert "</b>")
    (goto-char start) (insert "<b>")
    ))

You can use this code to wrap a HTML/XML tag on a selected text, or wrap brackets.

select-current-word, select-current-line

This code shows you how to set a mark (select text) programmatically.

(transient-mark-mode 1)

(defun select-current-word ()
"Select the word under cursor.
“word” here is considered any alphanumeric sequence with “_” or “-”."
 (interactive)
 (let (pt)
   (skip-chars-backward "-_A-Za-z0-9")
   (setq pt (point))
   (skip-chars-forward "-_A-Za-z0-9")
   (set-mark pt)
 ))
(transient-mark-mode 1)

(defun select-current-line ()
  "Select the current line"
  (interactive)
  (end-of-line) ; move to end of line
  (set-mark (line-beginning-position)))

See also: Emacs: What's Region, Active Region, transient-mark-mode?.

Find/Replace Text Region

This code illustrates how to do text replacements on a region. Very useful. For example, you can use it to replace HTML characters that needs to be encoded. For example:

(defun replace-html-chars-region (start end)
  "Replace “<” to “<” and other chars in HTML.
This works on the current region."
  (interactive "r")
  (save-restriction 
    (narrow-to-region start end)
    (goto-char (point-min))
    (while (search-forward "&" nil t) (replace-match "&" nil t))
    (goto-char (point-min))
    (while (search-forward "<" nil t) (replace-match "<" nil t))
    (goto-char (point-min))
    (while (search-forward ">" nil t) (replace-match ">" nil t))
    )
  )

You can modify the code to do replacement on URL Percent Encoding. For example:

and so on. You can also use it to do Greek Letter replacement when writing math. For example: alpha → α, beta → β, … etc.

For some detailed lesson on this code, see: Repeated Find Replace.

delete-enclosed-text

This code illustrates how to delete a text enclosed by any pairs of delimiters.

For example, if you are editing HTML code, suppose you have text <p>good morn and this is a long sentence …</p> and your cursor is somewhere in between the tags. You want to quickly delete all texts inside the p tags. The following function will do. It will also, delete any text between quotes or parenthesis.

(defun delete-enclosed-text ()
  "Delete texts between any pair of delimiters."
  (interactive)
  (save-excursion
    (let (p1 p2)
      (skip-chars-backward "^([<>“") (setq p1 (point))
      (skip-chars-forward "^)]<>”") (setq p2 (point))
      (delete-region p1 p2))))

For many related code, see: Suggestions on Emacs's mark-word Command: extend-selection, select-text-in-quote, select-current-line, select-current-block

Delete Linebreaks

This example shows how to temporarily change a pre-defined variable's value, then call a function whose behavior depends on the var.

(defun remove-line-breaks () 
  "Remove line endings in a paragraph."
  (interactive) 
  (let ((fill-column (point-max))) 
    (fill-paragraph nil)))

fill-paragraph is a function that hard-wraps the current paragraph. (it removes some space character and inserts newline character at every ≈70 characters) fill-column is a variable used by fill-paragraph to determine where to chop. It has a value of 70 by default.

The above code temporarily set fill-column to a large number (point-max), then, it calls fill-paragraph. So, effectively, it replaces all newline char by space in the current paragraph. (Note: “paragraph” may be different depending on the major mode. Its dependent on syntax table. If it doesn't work, try switching mode, to text-mode.)

For more detail, see: Emacs unfill-paragraph, unfill-region, compact-uncompact-block.

Next/Previous User Buffer

In this example, simple lisp constructions are shown, including while, and, string-match. This is also a very convenient function. It allows you to switch to the next buffer without going thru a bunch of irrelevant buffers that emacs created, ⁖ {*scratch*, *Messages*, *Shell Command Output*, *Completions*, *calc*, *grep*, …}.

(defun next-user-buffer ()
  "Switch to the next user buffer.
User buffers are those whose name does not start with *."
  (interactive)
  (next-buffer)
  (let ((i 0))
    (while (and (string-equal "*" (substring (buffer-name) 0 1)) (< i 20))
      (setq i (1+ i)) (next-buffer))))
(defun previous-user-buffer ()
  "Switch to the previous user buffer.
User buffers are those whose name does not start with *."
  (interactive)
  (previous-buffer)
  (let ((i 0))
    (while (and (string-equal "*" (substring (buffer-name) 0 1)) (< i 20))
      (setq i (1+ i)) (previous-buffer) )))

You can set a key for them similar for browser's next/previous tab.

(global-set-key (kbd "C-<prior>") 'previous-user-buffer) ; Ctrl+PageDown
(global-set-key (kbd "C-<next>") 'next-user-buffer) ; Ctrl+PageUp

Inserting a Random Number

I needed a fast way to insert random numbers. So i wrote:

(random t) ; seed it randomly

(defun insert-random-number ()
  "Insert a random number between 0 to 999999."
  (interactive)
  (insert (number-to-string (random 999999))) )

(defun insert-random-hex ()
  "Insert a random 4-digit hexidecimal number."
  (interactive)
  (let (myCharset (possibleCharsCount 16))
    (setq myCharset "1234567890abcdef" )
    (dotimes (ii 4)
      (insert (elt myCharset (random possibleCharsCount))) ) )
  ;; (insert (format "%4x" (random 65535)) )
  )

Elisp does not automatically convert number to string. So, number-to-string is very convenient. There's also string-to-number.

Once i defined this function, i can either give it a Keyboard Shortcut.

Exercise: write a command that insert current date/time. (answer can be found at: How to Update Webfeed with Emacs Lisp)

Thanks to Marcin Milewski for a correction on “wrap-markup”.

blog comments powered by Disqus