I have a number of utility functions in a file called
my-utils.el. The first one I wrote was
(defun add-path (&rest path) (let ((full-path "")) (dolist (var path) (setq full-path (concat full-path var))) (add-to-list 'load-path (expand-file-name full-path))))
This means that when I add a new third-party library (in its own directory), I can just write:
(add-path *elisp-dir* "muse-3.12")
I have a function called
identity that returns whatever was passed to it.
(defun identity (e) e)
This is particularly useful in functions like
(defun add-path (&rest path) (add-to-list 'load-path (mapconcat #'identity path "")))
I like this function that I found on the internet a while ago (can’t find it again for attribution unfortunately).
(defun insert-YYYMMDD () (interactive) (insert (format-time-string "%Y%m%d")))
remove-dupes removes duplicate items that are next to each other in a list in the same way that
uniq does. (I mentioned this previously in one of the enabling your users posts.)
(defun remove-dupes (list) (let (tmp-list head) (while list (setq head (pop list)) (unless (equal head (car list)) (push head tmp-list))) (reverse tmp-list)))
Sometimes you will have an assocation list where you just want to replace one of the values.
(defun assoc-replace (seq values) "Replace an element within an association list where the cars match." (mapcar (lambda (elem) (let* ((key (car elem)) (val (assoc key values))) (if val (cadr val) elem))) seq))
And often, only the cdr needs to change so
kv is a shortcut for that case.
(kv 'a 'b) returns
(a (a . b)).
(defsubst kv (k v) `(,k (,k . ,v)))
(These functions were mentioned in emacs association lists)
ext-mode-map allows me to easily setup a major mode for extensions that are inconsistently capitalized.
(defun file-extensions (l) (concat "\\.\\(" (mapconcat (lambda (s) (mapconcat (lambda (c) (let ((c (upcase (char-to-string c)))) (concat "[" c (downcase c) "]"))) (symbol-name s) "")) l "\\|") "\\)\\'")) (defun ext-mode-map (extensions mode) (cons (file-extensions extensions) mode))
Then, for example, I can setup my perl extensions like this:
(add-to-list 'auto-mode-alist (ext-mode-map '(pl perl pm) 'cperl-mode))
(These functions were previously mentioned in autoloading an emacs major mode)
I’m still using this function to duplicate the current line. It works unless you are on the final line which is very rare and you can work around that by opening a line below.
(defun duplicate-current-line () (interactive) (beginning-of-line nil) (let ((b (point))) (end-of-line nil) (copy-region-as-kill b (point))) (beginning-of-line 2) (open-line 1) (yank) (back-to-indentation))
(This function was mentioned previously in A Simple Emacs Shortcut – Duplicate Line)
I often copy text into buffer and want to read it nicely wrapped around. I’ll change this function to use
visual-line-mode when all my emacs versions are upgraded to 23.
(defun set-longlines-mode () (interactive) (text-mode) (longlines-mode 1))
Other people have talked about their own
count-words functions in the past. I have my own ideas about what constitutes a word.
(defun count-words () (interactive) (let ((words (count-matches "[-A-Za-z0-9][-A-Za-z0-9.]*" (point-min) (point-max)))) (message (format "There are %d words" words))))
regex-replace and string-repeat
I sometimes have a text transform that I want to apply globally to a buffer. Exercise for the reader, fix
regex-replace to only apply to a region if one is selected.
(defun regex-replace (regex string) (goto-char (point-min)) (while (re-search-forward regex nil t) (replace-match string))) (defun string-repeat (str n) (let ((retval "")) (dotimes (i n) (setq retval (concat retval str))) retval))