Xah Lee, 2005-11, ..., 2009-11-12
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-function 【Ctrl+h f】. A variable's documentation is describe-variable 【Ctrl+h v】.
If you do not know the basics of lisp, goto: elisp basics.
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, etc. (but if you want a systematic set of templates/snippets, better is Emacs Templates with YASnippet.)
This code shows how to place a string at the beginning and end of a region.
(defun wrap-markup () "Insert a markup <b></b> around a region." (interactive) (goto-char (region-end)) (insert "</b>") (goto-char (region-beginning)) (insert "<b>") )
You can use this code to wrap a html/xml tag on a selected text.
This code shows you how to set a mark (select text) programatically.
(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?.
This code illustrates how to do text replacements on a region. Very useful. For example, you can use it to replace HTML character that needs 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's Percent-encoding. For example:
“ ” → “%20” “~” → “%e7” “_” → “%5f”
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.
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>how howdy, and blab blab blab</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))))
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 inserts line-break char at about every 70 characters) fill-column is a variable used by fill-paragraph to determine when to chop. It has a value of 70 by default.
The above code, temporarily set fill-column to a huge number (point-max), then, it calls fill-paragraph. So, effectively, it replaces all line-break chars by spaces in the current paragraph.
For more detail, see: Emacs unfill-paragraph, unfill-region, compact-uncompact-block.
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 such as “*scratch*”, “*Messages*”, “*Shell Command Output*”, “*Completions*”, etc.
(defun next-user-buffer () "Switch to the next user buffer in cyclic order.\n User buffers are those not starting with *." (interactive) (next-buffer) (let ((i 0)) (while (and (string-match "^*" (buffer-name)) (< i 50)) (setq i (1+ i)) (next-buffer) ))) (defun previous-user-buffer () "Switch to the previous user buffer in cyclic order.\n User buffers are those not starting with *." (interactive) (previous-buffer) (let ((i 0)) (while (and (string-match "^*" (buffer-name)) (< i 50)) (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
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-hexinumber () "Insert a random 4-digit hexidecimal number, with 0 padded in front." (interactive) (insert (format "0%4x" (random 65535)) ) )
If you are new to lisp... notice that 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, or define a alias. I have already too many shortcuts, so i just define a alias, by 「(defalias 'irn 'insert-random-number)」. Then, when i need to have a random number inserted, i just type 【Alt+x irn】.
Exercise: write a command that insert current date/time. (answer can be found at: How to Update Webfeed with Emacs Lisp)