Elisp: Simple Code Examples

By Xah Lee. Date: . Last updated: .

This page shows very simple and useful emacs lisp commands that are shorter than 10 lines. They show you the basic programing in elisp.

Insert Text

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

(defun my-insert-p-tag ()
  "Insert <p></p> at cursor point."
  (insert "<p></p>")
  (backward-char 4))
  1. Copy the code into a buffer.
  2. Eval the code. [see Emacs: Evaluate Elisp Code]
  3. Call the code by Alt+x

You can use this code to insert your {template, header, etc}.

To see a function's documentation, see Emacs: Lookup Function Documentation

Insert Around Region

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

(defun my-wrap-markup-region ()
  "Insert a markup <b></b> around a region."
  (let ((p1 (region-beginning))
        (p2 (region-end)))
    (goto-char p2)
    (insert "</b>")
    (goto-char p1)
    (insert "<b>")))

You can use this code to add HTML begin/end tag on a selected text, or add brackets around a selection.

Exercise: modify this do ask user what html tag use.

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

Select Current Word

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

;; turn on highlight selection
(transient-mark-mode 1)

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

Select Current Line

;; turn on highlight selection
(transient-mark-mode 1)

(defun my-select-current-line ()
  "Select the current line"
  (let ((pos (line-beginning-position)))
    (set-mark pos)))

See also: Elisp: Mark, Region, Active Region.

Exercise: write a command to select current text block. (text block are separated by empty lines.)

Find Replace String in Region

Here's how to do text replacements on a region.

(defun my-replace-greek-region ()
  "Replace “alpha” to “α” and other greek letters in current region."
  (let (
        (p1 (region-beginning))
        (p2 (region-end)))
      (narrow-to-region p1 p2)
      (goto-char (point-min))
      (while (search-forward " alpha" nil t)
        (replace-match " α" nil t))
      (goto-char (point-min))
      (while (search-forward " beta" nil t)
        (replace-match " β" nil t))
      (goto-char (point-min))
      (while (search-forward " gamma" nil t)
        (replace-match " γ" nil t)))))

You can modify the code to do other replacements. For example, HTML/XML Entitie.

Exercise: make this do current buffer, or current line.

Delete Enclosed Text

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

For example, if you are editing HTML code, suppose you have text

<p>something something long …</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 my-delete-enclosed-text ()
  "Delete texts between any pair of delimiters."
    (let (p1 p2)
      (skip-chars-backward "^([<>“")
      (setq p1 (point))
      (skip-chars-forward "^)]<>”")
      (setq p2 (point))
      (delete-region p1 p2))))

Delete Linebreaks

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

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

Inserting a Random Number

(random t) ; seed it randomly

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

Reference Lookup

This example shows the use of thing-at-point and browse-url.

It will look up the word under the cursor in a online dictionary.

(defun my-word-definition-lookup ()
"Look up the word under cursor in a browser."
   (concat "https://www.thefreedictionary.com/" (thing-at-point 'symbol))))

Change Newline Character

This example shows how to define a function that takes a file path and process the file.

(defun my-to-unix-eol (fPath)
  "Change file's line ending to unix convention."
  (let ((myBuffer (find-file fPath)))
    (set-buffer-file-coding-system 'unix) ; or 'mac or 'dos
    (kill-buffer myBuffer)))

For example, if the file ~/readme.txt is a Windows file, you can change its line ending by evaluating the following:

(to-unix-eol "~/readme.txt")

The following example shows how to apply a file processing function to a list of files.

(mapc 'to-unix-eol
;   )

The following wraps it as a command, so can be called in dired. It acts on all marked files.

(defun my-dired-2unix-marked-files ()
  "Change to unix line ending for marked (or next arg) files."
  (mapc 'to-unix-eol (dired-get-marked-files))

Delete Current File

This example shows command that lets you delete the current file. Note here that elisp is used to: {manipulate buffer, manipulate file, prompt user}.

(defun my-delete-current-file ()
  "Delete the file associated with the current buffer.
Delete the current buffer too.
If no file is associated, just close buffer without prompt for save."
  (let ((currentFile (buffer-file-name)))
    (when (yes-or-no-p (concat "Delete file?: " currentFile))
      (kill-buffer (current-buffer))
      (when currentFile
        (delete-file currentFile)))))

Highlighting Lines

This example shows you how to make lines containing the words “ERROR:” or “NOTE:” highlighted, whenever a file ending in “log” is opened.

(defun my-highlite-it ()
  "Highlight certain lines…"
  (if (equal "log" (file-name-extension (buffer-file-name)))
        (highlight-lines-matching-regexp "ERROR:" 'hi-red-b)
        (highlight-lines-matching-regexp "NOTE:" 'hi-blue-b))))

(add-hook 'find-file-hook 'highlite-it)

Insert Vertical Column of Numbers

This commands insert a vertical column of numbers into a block of text, like this:

1. x
2. x
3. x
4. x
(defun my-insert-column-counter (n)
  "Insert a sequence of numbers vertically.
For example:

c d
e f


a1 b
c2 d
e3 f

If there are not enough existing lines after the cursor
when this function is called, it aborts at the last line.

This command is conveniently used together with `kill-rectangle' and `string-rectangle'.
Version 2019-01-27"
  (interactive "nEnter the max integer: ")
  (let ((i 1) colpos )
    (setq colpos (- (point) (line-beginning-position)))
    (while (<= i n)
      (insert (number-to-string i))
      (forward-char colpos)
      (setq i (1+ i)))))

Note: Emacs 24 (Released 2012-06) has a new command rectangle-number-lines.