Sei sulla pagina 1di 102

Elisp Snippets

Table of Contents
• 1. Elisp Snippets
• 1.1. Overview
• 1.2. Strings
• 1.2.1. Concatenate strings
• 1.2.2. Join Strings by Separator
• 1.2.3. Split String
• 1.2.4. Split String with quotes
• 1.2.5. Replace Strings
• 1.2.6. Regex
• 1.3. Text Manipulation
• 1.3.1. Text alignment
• 1.3.2. Join Multiple Lines
• 1.4. S-expressions
• 1.4.1. Parse s-expressions
• 1.4.2. Evaluate s-expressions
• 1.5. Clipboard (Kill-ring)   
• 1.5.1. Copy string to clipboard
• 1.5.2. Paste string from clipboard
• 1.5.3. Copy buffer file name to clibpoard
• 1.5.4. Copy buffer directory to clibpoard
• 1.5.5. Copy buffer content to clipboard
• 1.6. Elisp
• 1.6.1. Load an Elisp file
• 1.6.2. Load all elisp files of a directory
• 1.6.3. Add directory to load path
• 1.6.4. Switch and Create the Scratch Buffer
• 1.6.5. Eval String in Clipboard
• 1.6.6. Extract Function Documentation   
• 1.6.7. Describe function
• 1.7. Common Lisp Emulation Library
• 1.7.1. Reduce (fold left) function
• 1.8. Buffer and regions
• 1.8.1. Save buffer
• 1.8.2. Kill / delete buffer
• 1.8.3. Get buffer content as string
• 1.8.4. Get selected text as string
• 1.8.5. Create a scratch buffer for Programming Languages
• 1.8.6. Get all buffer's local variables
• 1.8.7. Get a specific buffer local variable
• 1.8.8. Append buffer content to file
• 1.8.9. Write file with buffer content (overwrite file it exists)
• 1.8.10. Revert / update buffer without asking to confirm
• 1.9. IO - Input and Output
• 1.9.1. Input - Read User Input
• 1.9.2. Output
• 1.10. Interacting with Operating System and External Applications
• 1.10.1. Related Documentation
• 1.10.2. Add application path to the PATH variable - Solving command not found
• 1.10.3. Synchronous Shell Commands
• 1.10.4. Pipe a region to external command   
• 1.10.5. Launch apps in Asynchronous mode
• 1.10.6. Run asynchronous commands piping the output to a buffer
• 1.10.7. Run a ncurses / terminal app inside Emacs
• 1.10.8. Run apps in external terminal emulator   
• 1.10.9. Launch applicatiosn from Emacs
• 1.10.10. Send regions, commands and buffer to M-x shell repl.
• 1.11. Compilation   
• 1.11.1. Enhanced Compilation Command
• 1.11.2. Compile a single c++ file related to current buffer and run it.
• 1.11.3. Compile and run a single c++ file at point in dired mode
• 1.12. File
• 1.12.1. Test if file or directory exists
• 1.12.2. Expand file name
• 1.12.3. Read file to string
• 1.12.4. Open file to edit
• 1.12.5. Open file to edit silently   
• 1.12.6. Edit File as Root   
• 1.13. File Name Manipulation
• 1.13.1. Get absolute path to current buffer's file.
• 1.13.2. File name without path
• 1.13.3. File name to base name
• 1.13.4. Get file's path
• 1.13.5. Expand file name
• 1.13.6. Replace file extension
• 1.14. Directory   
• 1.14.1. Open directory
• 1.14.2. Create directory
• 1.14.3. List directory
• 1.15. Dired mode snippets   
• 1.15.1. Overview
• 1.15.2. Copy path of file at point
• 1.15.3. Paste a file from clibpboard
• 1.15.4. Create empty file (touch)
• 1.15.5. Open multiple marked files
• 1.15.6. Close multiple marked files
• 1.15.7. Open a file with default system application   
• 1.15.8. Close all dired buffers
• 1.15.9. Browse bookmarked directories   
• 1.15.10. Filter dired buffer by file extensions
• 1.15.11. Filter dired buffer by regex
• 1.15.12. Open directory at point with Microsoft Explorer in Windows OS.
• 1.16. Date Time
• 1.16.1. Overview
• 1.16.2. Function format-time-string
• 1.16.3. Function current-time
• 1.16.4. Function current-time-string
• 1.16.5. Function float-time
• 1.16.6. Function current-time-zone
• 1.17. Emacs Introspection
• 1.17.1. User init file
• 1.17.2. User Emacs Directory
• 1.17.3. Enviroment Variables
• 1.17.4. Get current Operating System
• 1.17.5. Test if Emacs is running in terminal or in window system
• 1.18. Web Browser   
• 1.18.1. Browse Url
• 1.18.2. Browser Url setting the web browser
• 1.18.3. Search Web sites with Emacs   
• 1.18.4. Browser Inside Emacs
• 1.19. Http Requests   
• 1.19.1. Download File   
• 1.19.2. url-retrieve-synchronously   
• 1.19.3. Download a file interactively   
• 1.19.4. Download a file and display it on a buffer   
• 1.19.5. Http and Post Request   
• 1.20. Packages   
• 1.20.1. Test if package is installed
• 1.20.2. Install a package if it is not installed
• 1.20.3. Install a single-file package from URL
• 1.21. Helm Snippets   
• 1.21.1. Switch between buffers in same directory
• 1.21.2. Browser Recent files
• 1.21.3. Browser Recent directories
• 1.21.4. Launch ansync shell command with helm
• 1.21.5. Switch between buffers associated with files
• 1.21.6. Switch between Emacs major modes
• 1.21.7. Open a list of web sites
• 1.21.8. Interface Makefile
• 1.22. Persistence
• 1.22.1. Save and Reload Current Session
• 1.22.2. Save and Restore Current Window Configuration
• 1.23. Non categorized
• 1.23.1. Save the scratch buffer and reload every Emacs startup
• 1.23.2. Code Navigation with Occur   
• 1.23.3. Quick edit and reload Emacs Configuration File.   
• 1.23.4. Refresh / Revert buffer without confirmation.
• 1.23.5. Create a menu with all color themes available
• 2. IELM - Inferior Emacs Lisp Mode
• 2.1. Change Prompt
• 2.2. Clear IELM shell
• 2.3. Send Region to IELM
• 2.4. Set other window's buffer as working buffer
• 2.5. Start IELM in other window setting the working buffer to current buffer
• 2.6. Launch IELM in other frame
• 3. Emacs Server and Client
• 4. Org-mode
• 5. Selected Gists and Source Codes
• 5.1. Gists
• 5.2. Source Codes
Top

1 Elisp Snippets

1.1 Overview
This section provides Elisp snippets and examples about Emacs API to help developers find what they
need quickly.

1.2 Strings
1.2.1 Concatenate strings
> (concat "hello" " world")
"hello world"

> (concat "hello" " world" " elisp ")


"hello world elisp "

> (apply #'concat '("hello" " world " " elisp "))
"hello world elisp "

1.2.2 Join Strings by Separator


(defun join (sep lst)
(mapconcat 'identity lst sep))

ELISP> (join "," '("1.232" "300" "500"))


"1.232,300,500"

ELISP> (join ", " '("1.232" "300" "500"))


"1.232, 300, 500"

1.2.3 Split String


> (split-string "100,200,300,400" ",")
("100" "200" "300" "400")

> (split-string (getenv "PATH") ":")


("/usr/local/sbin" "/usr/local/bin" "/usr/bin" ...)

1.2.4 Split String with quotes


> (split-string-and-unquote "/bin/app -x -y -z \"/home/user/some name with space/
etc\" -k cmd ")

("/bin/app" "-x" "-y" "-z" "/home/user/some name with space/etc" "-k" "cmd")

1.2.5 Replace Strings

1.2.6 Regex

1.3 Text Manipulation


1.3.1 Text alignment
Source: Init file - www.svjatoslav.eu
(defun align-to-colon (begin end)
"Align region to colon (:) signs"
(interactive "r")

(align-regexp begin end


(rx (group (zero-or-more (syntax whitespace))) ":") 1 1 ))

(defun align-to-comma (begin end)


"Align region to comma signs"
(interactive "r")
(align-regexp begin end
(rx "," (group (zero-or-more (syntax whitespace))) ) 1 1 ))

(defun align-to-equals (begin end)


"Align region to equal signs"
(interactive "r")
(align-regexp begin end
(rx (group (zero-or-more (syntax whitespace))) "=") 1 1 ))

(defun align-to-hash (begin end)


"Align region to hash ( => ) signs"
(interactive "r")
(align-regexp begin end
(rx (group (zero-or-more (syntax whitespace))) "=>") 1 1 ))

;; work with this


(defun align-to-comma-before (begin end)
"Align region to equal signs"
(interactive "r")
(align-regexp begin end
(rx (group (zero-or-more (syntax whitespace))) ",") 1 1 ))
1.3.2 Join Multiple Lines
From: jidaikobo-shibata/join-multi-lines-to-one.el
(defun join-multi-lines-to-one ()
"Join multi lines."
(interactive)
(let ((beg (region-beginning))
(end (region-end))
strings)
(goto-char beg)
(back-to-indentation)
(setq beg (point))
(goto-char end)
(goto-char (- (point) 1))
(end-of-line)
(setq end (point))
(setq strings (buffer-substring-no-properties beg end))
(setq strings (replace-regexp-in-string "\n\\|^>+ *\\|^[\t  ]+" " " strings))
(setq strings (replace-regexp-in-string " +" " " strings))
(delete-region beg end)
(insert strings)
(goto-char beg)))

1.4 S-expressions

1.4.1 Parse s-expressions


;; Exaluate with M-x eval-print-last-sexp

> (read "(mapc (lambda (p) (insert p) (insert \"\n\"))


(buffer-list))
")

(mapc (lambda (p) (insert p) (insert "


")) (buffer-list))

> (read "(+ 1 2 3 4)")


(+ 1 2 3 4)
1.4.2 Evaluate s-expressions
> (eval (read "(+ 1 2 3 4)" ))
10

> (eval '(+ 1 2 3 4))


10

1.5 Clipboard (Kill-ring)   elisp clipboard kill ring

1.5.1 Copy string to clipboard


(defun clipboard/set (astring)
"Copy a string to clipboard"
(with-temp-buffer
(insert astring)
(clipboard-kill-region (point-min) (point-max))))

1.5.2 Paste string from clipboard


(defun clipboard/get ()
"Return the content of clipboard as string"
(interactive)
(with-temp-buffer
(clipboard-yank)
(buffer-substring-no-properties (point-min) (point-max))))

1.5.3 Copy buffer file name to clibpoard


(defun buffer/copy-file-name ()
(interactive)
(clipboard/set (buffer-file-name)))

;; Eval using M-x eval-print-last-sexp


;;
> (buffer/copy-file-name)
nil

> (insert (clipboard/get))


/home/arch/projects/emacs/Emacs_Snippets.org

1.5.4 Copy buffer directory to clibpoard


(defun buffer/copy-path ()
(interactive)
(clipboard/set (file-name-directory (buffer-file-name)))
(message "Copied file path to clipboard"))

;; Eval using M-x eval-print-last-sexp


;;
> (buffer/copy-path)
"Copied file path to clipboard"

> (clipboard/get)
"/home/arch/projects/emacs/"
1.5.5 Copy buffer content to clipboard
(defun buffer/copy-content ()
"Copy buffer content to clibpoard
Usage: M-x buffer/copy-content"
(interactive)
(clipboard/set
(buffer-substring-no-properties
(point-min)
(point-max)
)))

1.6 Elisp

1.6.1 Load an Elisp file


Load an elisp source file *.el.
(load-file "~/.emacs.d/tools.el")

Load an byte-compiled (*.elc) elisp file.


(load-file "~/.emacs.d/tools.elc")

1.6.2 Load all elisp files of a directory


(defun load-dir (path)
"
Load all elisp files (*.el) of a directory

Usage: (load-dir <path>)

Example: (load-dir \"~/.emacs.d/custom\")

"
(mapc #'load (directory-files path t "\\.el$")))

1.6.3 Add directory to load path


It adds a directory containing Emacs packages (<package name>.el) to the load path. The user can load
packages by adding the code (require '<package>) to the file init.el.
(add-to-list 'load-path "~/.emacs.d/custom")

;; package -> ~/.emacs.d/custom/package.el


;;
(require 'package)
1.6.4 Switch and Create the Scratch Buffer
This function switches and crates the scratch buffer if it doesn't exist or was deleted. Usage: M-x
scratch.
(defun scratch ()
"
Switches to scratch buffer and creates
it if it doesn't exist.

Usage: M-x scratch

This function is useful to Elisp developers.

Suggestion:
Add (defalias 's #'scratch) to the init file.
You can switch to the scratch buffer with > M-x s
"

(interactive)

(let ((buf (get-buffer-create "*scratch*")))

(switch-to-buffer buf)
(lisp-interaction-mode)
))

(defalias 's #'scratch)

1.6.5 Eval String in Clipboard


It only works on Linux and requires Xclip to be installed, but with a few changes can be tweaked to
work in another Os.
ELISP> (defun eval-string (str) (eval (read str)))
eval-string

ELISP> (defun eval-xclip () (eval-string (shell-command-to-string "xclip -o")))


eval-xclip

;;
;; Copy the following line in this comment block
;;
;; (message "Loading my copypaste file...")

ELISP> (eval-xclip)
"Loading my copypaste file..."
ELISP>
1.6.6 Extract Function Documentation   elisp
Source: Generate emacs-lisp documentation Primitives:
ELISP>
ELISP> (defun sample-function (a b c)
"Function Docstring"
(+ a (* 5 b) (* 3 c)))

;; Extract Documentation
;;
ELISP> (documentation 'sample-function)
"Function Docstring"

;; Extract Code
;;
ELISP> (symbol-function 'sample-function)
(lambda
(a b c)
"Function Docstring"
(+ a
(* 5 b)
(* 3 c)))

;; Extract Arguments
ELISP> (help-function-arglist 'sample-function)
(a b c)

Final Code
(fun2org 'sample-function)
"** sample-function (a b c)\nFunction Docstring\n\n#+BEGIN_SRC emacs-lisp\
n(lambda (a b c) \"Function Docstring\" (+ a (* 5 b) (* 3 c)))\n#+END_SRC\n"
ELISP>
ELISP> (defun fun2org (function-symbol)
(let ((args (help-function-arglist function-symbol))
(doc (documentation function-symbol))
(code (symbol-function function-symbol)))
(print (format "** %s %s
%s

#+BEGIN_SRC emacs-lisp
%S

" function-symbol args doc code)))) ;; End of fun2org

ELISP> (fun2org 'sample-function)

"** sample-function (a b c)
Function Docstring

(lambda (a b c) \"Function Docstring\" (+ a (* 5 b) (* 3 c)))


"
1.6.7 Describe function
(describe-function 'find-file-noselect)

1.7 Common Lisp Emulation Library


1.7.1 Reduce (fold left) function
1. Build a number from a list of digits
(require 'cl)

ELISP> (cl-reduce (lambda (acc x) (+ (* 10 acc) x)) '(1 2 3 4 5 6) :initial-


value 0)
123456 (#o361100, #x1e240)

2. Test if all values of a list are true


(require 'cl)

ELISP> (cl-reduce (lambda (acc x) (and acc x)) '(t nil t t t f) :initial-
value t)
nil
ELISP> (cl-reduce (lambda (acc x) (and acc x)) '(t t t t t f) :initial-value
t)
f
ELISP> (cl-reduce (lambda (acc x) (and acc x)) '(t t t t t t) :initial-value
t)
t

(defun all-p (bool-list)


"Tests if all values of bool-list are true (not nil)"
(cl-reduce (lambda (acc x) (and acc x)) bool-list :initial-value t))

ELISP> (all-p '(t t t))


t
ELISP> (all-p '(t nil t))
nil

3. Test if at least one value of a list is true


ELISP> (cl-reduce (lambda (acc x) (and acc x)) '(t t t t t t) :initial-value
t)
t
ELISP> (cl-reduce (lambda (acc x) (or acc x)) '(t t t t t t) :initial-value
nil)
t
ELISP> (cl-reduce (lambda (acc x) (or acc x)) '(nil nil nil t t
nil) :initial-value nil)
t
ELISP> (cl-reduce (lambda (acc x) (or acc x)) '(nil nil nil nil nil
nil) :initial-value nil)
nil
ELISP> ()
(defun some-p (bool-list)
"Tests if at least one value bool-list is true (not nil)"
(cl-reduce (lambda (acc x) (or acc x)) bool-list :initial-value nil))

ELISP> (some-p '(t t t t))


t
ELISP> (some-p '(nil t nil nil))
t
ELISP> (some-p '(nil nil nil nil))
nil

1.8 Buffer and regions

1.8.1 Save buffer


(save-buffer)

1.8.2 Kill / delete buffer


(kill-buffer <buffer-object or buffer-name>)

Example: Delete buffer named Elisp_Snippets.org


(kill-buffer "Elisp_Snippets.org")

Example: Delete all buffers:


(mapc #'kill-buffer (buffer-list))

1.8.3 Get buffer content as string


Returns the content of a buffer referencend by its name or the buffer object.
(defun buffer-content (&optional buffer-or-name)
(with-current-buffer (if buffer-or-name buffer-or-name (current-buffer))
(buffer-substring-no-properties (point-min) (point-max) )))

1.8.4 Get selected text as string


Returns the selected text of the current buffer.
(defun get-selection ()
"Get the text selected in current buffer as string"
(interactive)
(buffer-substring-no-properties (region-beginning) (region-end)))

1.8.5 Create a scratch buffer for Programming Languages


This function creates a Python scratch buffer like elisp *scratch* which allows the user to play with
Python without creating any file. It is possible to run
It can be easily changed to work with other languages like ruby by replacing python-mode to ruby-
mode.
Python Scratch buffer
Usage: M-x python/scratch
(defun python/scratch ()
(interactive)
(let (
;; Creates a new buffer object.
(buf (get-buffer-create "*python-scratch*"))
)
;; Executes functions that would change the current buffer at
;; buffer buf
(with-current-buffer buf
;;; Set the new buffer to scratch mode
(python-mode)
;;; Pop to scratch buffer
(pop-to-buffer buf)
)))

Shell (bash, sh) scratch buffer


Usage: M-x sh/scratch
(defun sh/scratch ()
(interactive)
(let (
;; Creates a new buffer object.
(buf (get-buffer-create "*sh-scratch*"))
)
;; Executes functions that would change the current buffer at
;; buffer buf
(with-current-buffer buf
;;; Set the new buffer to scratch mode
(sh-mode)
;;; Pop to scratch buffer
(pop-to-buffer buf)
)))

1.8.6 Get all buffer's local variables


Get all current buffer's local variables
(buffer-local-variables) ;; Evalute with M-x eval-print-last-sexp

Output:
((cursor-type . bar)
(buffer-display-time 22711 20278 987330 737000)
(buffer-display-count . 4)
(buffer-invisibility-spec
(org-babel-hide-hash . t)
(org-babel-hide-hash . t)
(org-babel-hide-hash . t)
(org-babel-hide-hash . t)
(org-babel-hide-result . t)
(org-hide-block . t)
(org-cwidth) (org-link) (outline . t) t)
(buffer-file-truename . "~/Documents/projects/emacs/Elisp_Snippets.org") (point-
before-scroll)

(buffer-auto-save-file-format . t)
(buffer-file-format) (buffer-file-coding-system . utf-8-unix)
(enable-multibyte-characters . t)
(mark-active)
(overwrite-mode) ...)

Get all local variables of a buffer.


(buffer-local-variables <buffer-name>)

1.8.7 Get a specific buffer local variable


(buffer-local-value VARIABLE BUFFER)

Get current buffer major-mode:


> (buffer-local-value 'major-mode (current-buffer))
org-mode

1.8.8 Append buffer content to file


Function append to file: Append buffer's region content to file.
(append-to-file <point-min> <point-max> <file-name>)

Append current buffer content to file. If the file doesn't exist, it will be created. Otherwise the buffer
content will be appended to the end of the file.
(append-to-file (point-min) (point-max) "/tmp/afile.txt")

Append a specific buffer content to file.


(with-current-buffer "my-buffer-name"
(append-to-file (point-min) (point-max) "/tmp/afile.txt"))

1.8.9 Write file with buffer content (overwrite file it exists)


;; Delete file if exists in order to overwrite it.
(if (file-exists-p filename)
(delete-file file))

;; Append buffer content to file.


(append-to-file (point-min) (point-max) filename))

1.8.10 Revert / update buffer without asking to confirm


(revert-buffer t t t)
1.9 IO - Input and Output

1.9.1 Input - Read User Input

1. Prompt functions

Function Description
read-string Read input as string
read-file-name Read input as file name
read-directory-name Read input as path to directory
read-regexp Read input as regular expression
read-passwd Read password
read-shell-command Read a shell command.
read-command Read an M-x elisp command returning a symbol.
read-envvar-name Read environment variable
read-key Read a key from the keyboard.
read-key-sequence Read a sequence of keystrokes and return as a string or vector.
read-number Read a numeric value
read-regexp Read regular expression returning it as string.
   

2. Read string
> (read-string "prompt > ") ;; M-x eval-print-last-sexp
"user enter some string in minibuffer"

Ask the user for a string and insert in the buffer


> (insert (concat "\n" (read-string " prompt > " ))) ;; M-x eval-last-sexp
user enter a message in the minibuffer

3. Read file name


Reads a file name from the user and gives auto completion. Enter tab to autocomplete the file
name.
> (read-file-name "Enter a file name: ") ;; M-x eval-print-last-sexp
"/etc/fstab"
4. Read file name and insert at point
Opens a prompt that asks for the path in the minibuffer with completion and inserts the path at
the current point.
• Usage: M-x insert-path
(defun insert-path ()
"
Opens a prompt that asks for the path
in the minibuffer with completion
and inserts the path at the current
point.

Usage: M-x insert-path

"
(interactive)
(insert (read-file-name "file > ")))

5. Read a directory path


> (read-directory-name "Enter a directory: ") ;; M-x eval-print-last-sexp
"/var/log"

1.9.2 Output

1. Message
Display a message at the bottom of the screen.
(message "A message to the user")
2. Print
3. Princ
4. Message box
Display a message, in a dialog box if possible. If a dialog box is not available, use the echo area.
(message-box "Emacs Alert. Time to drink a coffee!")

5. Tooltip
Show a tooltip
(tooltip-show "An Emacs tooltip")
1.10 Interacting with Operating System and External Applications

1.10.1 Related Documentation


[C-h-f] <name of function>
• shell-command
• async-shell-command
• start-process
• call-process
• shell-command-to-string
• shell-command-on-region
• getenv
• setenv

1.10.2 Add application path to the PATH variable - Solving command not found

1. Overview
In order to Emacs find where applications such as ruby shell, scala compiler and tools are
installed it is necessary to the PATH environment variable contain the path to the directories
which contains those applications.
2. Checking PATH variable
Copy this command below to the scratch buffer and enter M-x eval-print-last-last-sexp.
(getenv "PATH")
"/home/archbox/opt/scala/bin:/usr/bin:/bin: ..."

3. Command to display path variable


(defun show-path-variable ()
(interactive)
;; Create a new buffer to display results to user
(switch-to-buffer (get-buffer-create "*path-variable*"))
;; Clear buffer
(delete-region (point-min) (point-max))
;; save cursor position
(save-excursion
(mapc (lambda (p) (insert (concat p "\n")))
(split-string (getenv "PATH")
;; Get path separator (;) for Windows
;; and (:) for Unix-like systems.
(if (equal system-type 'windows/nt)
";"
":"
)))))

By running this command M-x show-path-varible it will print all paths in the $PATH variable in
a new buffer a easy way to read:
/home/archbox/opt/scala-2.11.8/bin
/home/archbox/opt/jdk1.8.0_74/bin/
/usr/local/sbin
/usr/local/bin
/usr/bin
/usr/lib/jvm/default/bin
/usr/bin/site_perl
/usr/bin/vendor_perl
/usr/bin/core_perl
/home/archbox/opt/java/bin
/home/archbox/opt/scala-2.11.8/bin/

4. Add a directories to PATH variable


It will add the directory: ~/opt/scala/bin to the $PATH variable. Before run the code below when
the user runs M-x async-shell-command scala it will shows an error message like this:
/bin/bash: scala: command not found

Note: The character ':' is the separator for Unix-like OS (Linux/ BSD and OSX) and ';' is the
separator for Windows.
;; Add single directory
(setenv "PATH"
(concat
(expand-file-name "~/opt/scala/bin") ":"
(getenv "PATH")))

;; Add multiple directories


(setenv "PATH"
(concat
(expand-file-name "~/opt/scala/bin") ":"
(expand-file-name "~/opt/jdk1.8.0_20/bin/") ":"
"/Applications/haste-compiler/bin/" ":"
(getenv "PATH")))

After it is done the Scala REPL will look like the picture below:
Figure 4: Scala in PATH variable.
5. Function to add multiple directories in PATH variable
(defun add-to-path-var (&rest pathlist)
(let* ((path-sep (if (equal system-type 'windows/nt)
";" ;; Windows separator
":" ;; Unix separator
)))
(setenv "PATH" (concat (apply #'concat
(mapcar
(lambda (path)
(concat (expand-file-name path)
path-sep))
pathlist))
(getenv "PATH")))))

Usage example:
(add-to-path-var "~/opt/scala/bin" "~/opt/jdk1.8.0_20/bin/")

Alternative way:
Use the function locally without pollute the namespace.
(require 'cl)

(cl-flet
((add-to-path-var
(&rest pathlist)
(let* ((path-sep (if (equal system-type 'windows/nt)
";" ;; Windows separator
":" ;; Unix separator
)))
(setenv "PATH"
(concat (apply #'concat
(mapcar
(lambda (path)
(concat (expand-file-name path)
path-sep))
pathlist))
(getenv "PATH"))))))
;; Add paths to be added to PATH variable here,
(add-to-path-var
"~/opt/scala/bin"
"~/opt/jdk1.8.0_20/bin/"
))

1.10.3 Synchronous Shell Commands

1. Display output of shell command


(shell-command "uname -a") ;; M-x eval-last-sexp

2. Display output of shell command in another frame   shell command frame


Display PCI cards in another frame.
(with-selected-frame (make-frame)
(shell-command "lspci"))

3. Shell Command To String   shell string


> (shell-command-to-string "uname -a") ;; M-x eval-print-last-sexp
"Linux localhost 4.7.0-1-ARCH #1 SMP PREEMPT Mon Aug 8 22:05:58 CEST 2016
x86_64 GNU/Linux
"

> (insert (format "\nKernel version %s " (shell-command-to-string "uname -


r"))) ;; M-x eval-last-sexp

Kernel version 4.7.0-1-ARCH


nil

(defun insert-debug-info ()
(interactive)

(insert (concat "Kernel version : ") (shell-command-to-string "uname -r"))


(insert (concat "Linux distribution : ") (shell-command-to-string "cat
/etc/issue"))
(insert (concat "Gcc version :") (shell-command-to-string "gcc --version |
grep GCC"))
)
;; M-x insert-debug-info

Kernel version : 4.7.0-1-ARCH


Linux distribution : Arch Linux \r (\l)

Gcc version :gcc (GCC) 6.1.1 20160802

4. Shell Command Wrappers


The function shell-command-to-lines runs a shell command and returns the output lines. This
function is useful to create shell command wrappers over Unix shell commands like find.
(defun shell-command-to-lines (command)
(remove-if-not (lambda (s) (/= (length s) 0))
(split-string
(shell-command-to-string command) "\n")))

ELISP> (mapc #'princ (shell-command-to-lines "ls /var/log"))


btmpfailloghttpdjournallastlogoldpacman.logsambaspeech-
dispatcherwtmpXorg.0.logXorg.0.log.old
("btmp" "faillog" "httpd" "journal" "lastlog" "old" "pacman.log" "samba"
"speech-dispatcher" "wtmp" "Xorg.0.log" "Xorg.0.log.old")

ELISP> (mapc (lambda (p) (princ p) (princ "\n")) (shell-command-to-lines


"ls /var/log"))
btmp
faillog
httpd
journal
lastlog
old
pacman.log
samba
speech-dispatcher
wtmp
Xorg.0.log
Xorg.0.log.old

Example: Shell command wrapper find


ELISP> (mapc (lambda (p) (princ p) (princ "\n")) (shell-command-to-lines
"find ~/.local/share/ -name \"*.desktop\""))
/home/arch/.local/share/xfce4/helpers/custom-WebBrowser.desktop
/home/arch/.local/share/applications/userapp-mono-IAJQMY.desktop
/home/arch/.local/share/applications/userapp-sh-9VFBMY.desktop
/home/arch/.local/share/applications/userapp-em-FLD8LY.desktop
/home/arch/.local/share/applications/userapp-mpv-FLQ9LY.desktop
/home/arch/.local/share/applications/userapp-Firefox-SOBHMY.desktop

(defun search-files (directory pattern)


(shell-command-to-lines
(format "find %s -name '%s'"
directory
pattern)))
ELISP> (search-files "~/.local" "*.desktop") ;; Output changed to fit in the
screen
("/home/arch/.local/share/xfce4/helpers/custom-WebBrowser.desktop"
"/home/arch/.local/share/applications/userapp-mono-IAJQMY.desktop"
"/home/arch/.local/share/applications/userapp-sh-9VFBMY.desktop"
"/home/arch/.local/share/applications/userapp-em-FLD8LY.desktop"
...
)

ELISP> (mapc (lambda (p) (princ p) (princ "\n")) (search-files "~/.local"


"*.desktop"))

/home/arch/.local/share/xfce4/helpers/custom-WebBrowser.desktop
/home/arch/.local/share/applications/userapp-mono-IAJQMY.desktop
/home/arch/.local/share/applications/userapp-sh-9VFBMY.desktop
/home/arch/.local/share/applications/userapp-em-FLD8LY.desktop
/home/arch/.local/share/applications/userapp-mpv-FLQ9LY.desktop
/home/arch/.local/share/applications/userapp-Firefox-SOBHMY.desktop

1.10.4 Pipe a region to external command   terminal shell command pipe interface

1. Pipe buffer or region to external command


Pipes the buffer content to external command and print the output in the buffer *Shell
Command Output*. The command $ wc -l counts the number of line of the current file.
> (shell-command-on-region (point-min) (point-max) "wc -l") ;; M-x eval-last-
sexp

Pipes the buffer content to external command $wc -l and get the output as a string.
> (with-output-to-string ;; M-x eval-print-last-sexp
(shell-command-on-region (point-min) (point-max) "wc -l"))
""

(defun pipe-region-to-command (pmin pmax command)


(interactive)
(shell-command-on-region
pmin
pmax
command
"*shell-output*")
(let ((output
(with-current-buffer "*shell-output*"
(buffer-substring-no-properties
(point-min)
(point-max)))))
(kill-buffer "*shell-output*")
output
))

> (pipe-region-to-command (point-min) (point-max) "wc -l") ;; M-x eval-print-


last-sexp
"1515
"

2. Apply an external command to buffer


The command below will pipe the buffer *scratch* to the command =$ sed 's/foo.*/bar/g'=
which replaces all values of foo for bar.
(with-current-buffer "*scratch*"
(shell-command-on-region
(point-min)
(point-max) "sed 's/foo.*/bar/g'" "*shell-output*" t )) ;; M-x eval-last-
sexp

Before the form evaluation

After the form evaluation.

3. Function to apply an external command to buffer


Usage: M-x shell-command-on-buffer Enter: sed 's/defun/defn/g' eplaces all defun words by
defn.
(defun shell-command-on-buffer (&optional command)
"Apply a shell command in the current buffer and replace it by the command
output.
Example:
- Interactive usage: M-x shell-command-on-buffer Enter: sed
's/defun/defn/g'.
replaces all defun words by defn.

- (shell-command-on-buffer \"sed 's/defun/defn/g'\")"


(interactive)
(shell-command-on-region (point-min)
(point-max)
(if command command (read-string "Cmd on buffer:
"))
"*shell-output*"
t
))

4. Insert line number in all lines of a buffer using ruby


Enter M-x shell-command-on-buffer and then $ ruby -ne 'printf("-%6s%s", $., $_)'
ruby -ne 'printf("-%6s%s", $., $_)'

Before running the command:

After running the command:


5. Ruby command on buffer
This function applies a ruby batch command on the buffer.
See also: Ruby One-Liners
(defun ruby-on-buffer (&optional command)
"Applies a ruby command on buffer
Example: The command will number each line of the current buffer.
1. M-x ruby-on-buffer
2. type: 'printf(\"%6s%s\", $., $_)' without quotes."
(interactive)
(shell-command-on-buffer
(format "ruby -ne '%s'"
(if command
command
(read-string "ruby cmd >")))))

6. Ruby regex on buffer


Emacs regexp islimited and doesn't have lookahead like perl or ruby regex. This command can
extend the functionality of Emacs regex using ruby. This function applies a ruby regex on the
buffer.
Usage: M-x ruby-gsub-on-buffer
See also: Ruby One-Liners
(defun ruby-gsub-on-buffer (&optional regexp)
"Applies ruby regex, the command $ ruby -pe 'gsub(regexp)' on the current
buffer.
Usage M-x ruby-gsub-on-buffer
(ruby-gsub-on-buffer <regexp>)
Example: The Command replace all occurrences of 'defun' by 'defn'.
1. M-x ruby-gsub-on-buffer
2. Type /defun/,\"defn\""
(interactive)
(shell-regexp-on-buffer
(format "ruby -pe 'gsub(%s)'"
(if regexp
regexp
(read-string "ruby regex: ")))))

Refactoring to a self-contained-code, removing all dependencies.


Example: To remove all numbers in at beggining of line run:
M-x replace-regex-ruby /^\d\d?/,""

(defun replace-regexp-ruby (&optional regexp)


"Replace ruby-gsub on buffer same as replace-regexp, but with ruby regex.
Usage M-x ruby-gsub-on-buffer
(ruby-gsub-on-buffer <regexp>)
Example: The Command replace all occurrences of 'defun' by 'defn'.
1. M-x ruby-gsub-on-buffer
2. Type /defun/,\"defn\""
(interactive)
(shell-command-on-region (point-min)
(point-max)
(format "ruby -pe 'gsub(%s)'"
(if regexp
regexp
(read-string "ruby regex: ")))
"*shell-output*"
t
))

1.10.5 Launch apps in Asynchronous mode

1.10.6 Run asynchronous commands piping the output to a buffer

1. Ping a host
• (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS

Usage: M-x ping-host or (ping-host <hostname>)


(defun ping-host (&optional hostname)
"Ping a hostname.
Usage:
- Interactive: M-x ping-host
- Command: (ping-host <hostname>)
Examples:
(ping-host \"www.google.com\")
(ping-host \"192.168.0.1\")"
(interactive)
(let ((hostname-
(if hostname
hostname
(read-string "host to ping: "))))
(start-process "ping" "*ping*" "ping" hostname-)
(switch-to-buffer-other-frame "*ping*")))

2. Tracerote a host
(defun traceroute-host (&optional hostname)
"Run traceroute command to test connection.
Usage:
- Interactive: M-x traceroute-host [Enter the hostname]
- Command: (traceroute-host <hostname>)
Example: (traceroute-host \"www.yahoo.co.uk\")."
(interactive)
(let ((hostname- (if hostname
hostname
(read-string "host to traceroute: "))))
(start-process "traceroute" "*traceroute*" "traceroute" hostname-)
(switch-to-buffer-other-frame "*traceroute*")))
1.10.7 Run a ncurses / terminal app inside Emacs
Run linux htop (task manager) inside Emacs:
(term "htop") ;; C-x C-e or M-x eval-last-sexp

1.10.8 Run apps in external terminal emulator   terminal shell os command


Some Linux ncurses-based applications like Htop, Top, Nmtui (Network Manager's terminal UI)
doesn't work well running in Emacs terminal emulator M-x term or M-x ansi-term. The solution
is run the command from Emacs and send to an external terminal emulator.
Read a command in launch in terminal
This command uses xfce4-terminal but it can be changed to any other terminal emulator.
(defun run-terminal ()
"Launch application in a terminal emulator."
(interactive)
(start-process
"termx"
nil
;; Change this for your terminal.
"xfce4-terminal" "-e" (read-shell-command "Shell: ")))

Launch specific commands


(defun shell-command-in-terminal (command)
(start-process
"termx"
nil
;; Change this for your terminal.
"xfce4-terminal" "-e" command))
To launch htop:
(shell-command-in-terminal "htop")

To launch nmtui:
(shell-command-in-terminal "nmtui")

Command M-x htop to launch htop.


(defun htop ()
"Launch htop task manager."
(interactive)
(shell-command-in-terminal "htop"))

1.10.9 Launch applicatiosn from Emacs


This command asks the user a shell command providing tab completion and launches an asynchronous
process (it doesn't freeze Emacs). Unlike asynchronous-shell-command this command doesn't create a
new buffer. It is useful to launch desktop GUI applications from Emacs like Firefox, terminal emulator,
file mangers and so on.
Note: In order to this command find the app the directory of the app must be in the $PATH variable.
(defun shell-launch ()
"Launch a process without creating a buffer. It is useful to launch apps from
Emacs."
(interactive)
(let* ((cmd-raw (read-shell-command "Launch command: "))
(cmd-args (split-string-and-unquote cmd-raw))
(cmd (car cmd-args)) ;; program that will run
(args (cdr cmd-args))) ;; command arguments
(apply #'start-process `(,cmd
nil
,cmd ,@args
))))

This comamnd can be bound to a keybiding with the code bellow that bidns the key combination
SUPER (Windows Key) + 8.
(global-set-key (kbd "s-8") #'shell-launch)

1.10.10 Send regions, commands and buffer to M-x shell repl.


• M-x shell/buffer-repl This command deletes all other windows and splits the current frame into
two windows one containing a M-x shell (bash) repl and the other a shell-script scratch buffer
(sh-mode).
• M-x shell/buffer-repl-frame Like the shell/buffer-repl, but shell and the scratch buffer are
displayed in new frame.
(defun shell/buffer-repl ()
"Create "
(interactive)
(delete-other-windows)

;; Split window vertically


(split-window-right)

;;; Run shell (bash on Linux)


(shell)

;;; Creates a scratch-shell buffer on other half of window


(let ((buf (get-buffer-create "*shell-buffer*")))
(with-current-buffer buf
(sh-mode)
(pop-to-buffer buf))))

(defun shell/buffer-repl-frame ()
(interactive)
(with-selected-frame (make-frame)
(shell/buffer-repl)))

This functions are useful to send regions, lines and regions to M-x shell repl from a shell-buffer or
shell scratch buffer to the repl.
(defun shell/send-region ()
"Send selected text to M-x shell repl."
(interactive)
(comint-send-region (get-buffer-process "*shell*" )
(region-beginning) (region-end))
(comint-send-string (get-buffer-process "*shell*" ) "\n"))

(defun shell/insert-region ()
"Insert selected text into M-x shell repl and run it."
(interactive)
(let ((text (buffer-substring-no-properties (region-beginning)
(region-end)
)))
(with-current-buffer "*shell*"
(insert text)
(comint-send-input)
)))

(defun shell/send-line ()
"Send current line to M-x shell repl."
(interactive)
(comint-send-region (get-buffer-process "*shell*")
(line-beginning-position)
(line-end-position)
)
(comint-send-string (get-buffer-process "*shell*" ) "\n"))

(defun shell/insert-line ()
"Insert current line to M-x shell repl."
(interactive)
(let ((line (buffer-substring-no-properties
(line-beginning-position)
(line-end-position)
)))
(with-current-buffer "*shell*"
(insert line)
(comint-send-input)
)))

(defun shell/execute-line ()
"Execute current line as shell command."
(interactive)
(shell-command
(buffer-substring (line-beginning-position)
(line-end-position))))

(defun shell/execute-region ()
"Execute current region as shell command."
(interactive)
(shell-command
(buffer-substring (region-beginning)
(region-end))))

(defun shell/insert-buffer ()
"Insert all buffer content into M-x shell repl and run it."
(interactive)
(let ((text (buffer-substring-no-properties (point-min)
(point-max)
)))
(with-current-buffer "*shell*"
(insert text)
(comint-send-input)
)))

Example:
1. User runs M-x shell/buffer-repl-frame. It will open a frame like in the picture bellow.
1. User select the region with some code and runs M-x shell/insert-region. It will send the current
region to the shell repl and display the output, in this case the content of root directory.
Figure 13: Example of M-x shell/buffer-repl-frame.
Figure 14: Demonstration of M-x shell/buffer-repl-frame and shell/insert-region

1.11 Compilation   compile tool building shell process

1.11.1 Enhanced Compilation Command


This command is similar to emacs M-x compile, however it expands '%f' to the buffer file name, '%n'
to buffer base name and '%d' to buffer directory.
Example: if the current buffer is associated to the file /home/arch/scripts/gui1.scala and the user types
the command M-x compile2 followed by the command below.
• $ scalac %f -d app-%n.jar && scala app-%n.jar

Emacs will run M-x compile with:


• $ scalac gui1.scala -d app-gui1.jar && scala scala app-gui1.jar

The advantage of this command is that user doesn't need to type the file name to be compiled.
(setq compile2-command-history "")

(defun compile2 ()
"Enhanced compilation command.
- %f - is expanded to current buffer file name.
- %d - is expanded to current buffer current directory.
- %n - is expanded to current buffer base name.

Example: if the current buffer is associated to the file.


- /home/arch/scripts/gui1.scala

If the user enter the command:

$ scalac %f -d app-%n.jar && scala app-%n.jar

It will run M-x compile with:

$ scalac gui1.scala -d app-gui1.jar && scala scala app-gui1.jar"


(interactive)
(let* ((file (buffer-file-name))
(cmd (read-shell-command "cmd> " compile2-command-history))
(cmd1 (replace-regexp-in-string "%f" (file-name-nondirectory file) cmd))
(cmd2 (replace-regexp-in-string "%n" (file-name-base file) cmd1))
(cmd3 (replace-regexp-in-string "%d" (file-name-directory file) cmd2)))
(setq compile2-command-history cmd)
(save-buffer)
(compile cmd3)))

1.11.2 Compile a single c++ file related to current buffer and run it.
Usage: When the user run the command M-x cpp/compile-run-buffer at the current buffer (file
code1.cpp) it will compile and run this file running the command $ g++ code1.cpp -o
code1.bin && ./code1.bin.
(defun cpp/compile-run-buffer ()
"Compile and run current c++ buffer (single-file C++ code).
Usage: By running M-x cpp/compile-buffer-run at current buffer (file code1.cpp)
will run $ g++ code1.cpp -o code1.bin && ./code1.bin"
(interactive)
(let* ((file-name (file-name-nondirectory (buffer-file-name)))
;; Change file name extension to .bin
(output (concat (file-name-base file-name) ".bin")))
(save-buffer)
(compile (format "g++ %s -o %s && ./%s"
file-name
output
output
))))

1.11.3 Compile and run a single c++ file at point in dired mode
Usage: In dired mode mode, place the cursor at the file to be compiled and run M-x cpp/compile-run-
dired.
(defun cpp/compile-run-dired ()
"Compile single c++ file at point in dired mode.
Usage: Position the cursor at the file to be compiled and
run M-x cpp/compile-dired."
(interactive)
(let* ((file-name (file-name-nondirectory (dired-file-name-at-point)))
;; Change file name extension to .bin
(output (concat (file-name-base file-name) ".bin")))
(save-buffer)
(compile (format "g++ %s -o %s && ./%s"
file-name
output
output
))))

1.12 File

1.12.1 Test if file or directory exists


> (file-exists-p "/var/log/pacman.log") ;; M-x eval-print-last-sexp
t

> (file-exists-p "/var/log/pcaman.log.err")


nil
;;
> (file-exists-p "/var/log")
t
;;
> (file-exists-p "/var/log-dont-exists")
nil

1.12.2 Expand file name


ELISP> (expand-file-name "~")
"/home/arch"

ELISP> (expand-file-name "~/.emacs.d/init.el")


"/home/arch/.emacs.d/init.el"

ELISP> (expand-file-name ".")


"/home/arch/projects/emacs"

1.12.3 Read file to string


The Emacs API doesn't provide a straightforward way to read file directly to a string. The only way to
perform this taks is using a temporary buffer.
(defun read-file (filename)
(with-temp-buffer
(insert-file-contents filename)
(buffer-substring-no-properties (point-min) (point-max))))

ELISP> (read-file "/etc/host.conf")


"#\n# /etc/host.conf\n#\n\norder hosts,bind\nmulti on\n\n# End of file\n"

ELISP> (princ (read-file "/etc/host.conf"))


#
# /etc/host.conf
#

order hosts,bind
multi on

# End of file

1.12.4 Open file to edit

1. Open file to edit in current window


> (find-file "/etc/fstab")

2. Open file to edit in anther window


(find-file-other-window "/etc/fstab")

3. Open file to edit in anther frame


(find-file-other-frame "/etc/fstab")

1.12.5 Open file to edit silently   file buffer open


Function: find-file-nonselect
Emacs Documentation: Read file FILENAME into a buffer and return the buffer.If a buffer exists
visiting FILENAME, return that one, but verify that the file has not changed since visited or saved. The
buffer is not selected, just returned to the caller.
Open a file and returns a buffer:
> (setq b1 (find-file-noselect "~/.bashrc"))
#<buffer .bashrc>
> b1
#<buffer .bashrc>

1.12.6 Edit File as Root   utils edit


(defun open-as-root (filename)
(interactive)
(find-file (concat "/sudo:root@localhost:" filename)))

;; Example:
;; ELISP> (open-as-root "/etc/host.conf")
;;

;;
;; Open an already opened buffer as root
;;
;; M-x open-buffer-as-root
;;
(defun open-buffer-as-root ()
(interactive)
(let
(
;; Get the current buffer file name
(filename (buffer-file-name (current-buffer)))
;; Get the current file name
(bufname (buffer-name (current-buffer)))
)
(progn
(kill-buffer bufname) ;; Kill current buffer
(open-as-root filename)))) ;; Open File as root

1.13 File Name Manipulation

1.13.1 Get absolute path to current buffer's file.


ELISP> (buffer-file-name)
"/home/archbox/.emacs.d/init.el"
ELISP>

1.13.2 File name without path


ELISP> (file-name-nondirectory "/home/archbox/.emacs.d/init.el")
"init.el"
ELISP>

1.13.3 File name to base name


Transform file name to name without path and extension.
ELISP> (file-name-base "/home/archbox/.emacs.d/init.el")
"init"
ELISP>
1.13.4 Get file's path
Get the directory that contais a file.
ELISP> (file-name-directory "/home/archbox/.emacs.d/init.el")
"/home/archbox/.emacs.d/"
ELISP>

1.13.5 Expand file name


ELISP> (expand-file-name ".")
"/home/archbox/.emacs.d"

ELISP> (expand-file-name "./init.el")


"/home/archbox/.emacs.d/init.el"
ELISP>

ELISP> (expand-file-name "~")


"/home/archbox"

ELISP> (expand-file-name "~/.bashrc")


"/home/archbox/.bashrc"
ELISP>

1.13.6 Replace file extension


Example: It will replace the extension of file name init.el to init.py. Note: it will not modify the file.
ELISP>
(let ((file "/home/archbox/.emacs.d/init.el"))
(concat (file-name-directory file)
(file-name-base file)
".py"
))

"/home/archbox/.emacs.d/init.py"
ELISP>

or
(defun file-replace-extension (ext file)
(concat (file-name-directory file)
(file-name-base file)
ext
))

ELISP> (file-replace-extension ".py" "/home/archbox/.emacs.d/init.el")


"/home/archbox/.emacs.d/init.py"
ELISP>

1.14 Directory   directory

1.14.1 Open directory


1. Open directory in current window
(dired "/var/log")

2. Open directory in another window


(dired-other-window "/var/log")

3. Open directory in another frame


(dired-other-frame "/var/log")

1.14.2 Create directory

1.14.3 List directory


Get directory content
ELISP> (directory-files "/var/log")

("." ".." "Xorg.0.log" "Xorg.0.log.old" ... )

Print the directory content in elisp shell IEML.


ELISP> (mapc #'(lambda (p) (princ (concat "\n" p)))
(directory-files "/var/log") )

.
..
Xorg.0.log
Xorg.0.log.old
btmp
faillog
httpd
journal
lastlog
old
pacman.log
samba
speech-dispatcher
wtmp

Get directory content with absolute file name.


ELISP> (directory-files "/var/log" t)
("/var/log/." "/var/log/.." "/var/log/Xorg.0.log" "/var/log/Xorg.0.log.old" ... )

ELISP> (mapc #'(lambda (p) (princ (concat "\n" p)))


(directory-files "/var/log" t ))

/var/log/.
/var/log/..
/var/log/Xorg.0.log
/var/log/Xorg.0.log.old
/var/log/btmp
...

List files of a specific extension:


;; Files ending with *.conf

ELISP> (directory-files "/etc/" nil "\\.conf")


("asound.conf" "dhcpcd.conf" "fuse.conf" "gai.conf" ...)

ELISP> (directory-files "/etc/" t "\\.conf")


("/etc/asound.conf" "/etc/dhcpcd.conf" "/etc/fuse.conf" ...)

ELISP> (directory-files "/etc/" t "\\.cfg")


("/etc/rc_maps.cfg" "/etc/vdpau_wrapper.cfg")

ELISP> (directory-files "/etc/" nil "\\.cfg")


("rc_maps.cfg" "vdpau_wrapper.cfg")

1.15 Dired mode snippets   directory dired

1.15.1 Overview
The dired mode is the mode used by Emacs to browser directories.
See also: How do you customize dired?
Source: hiroina/.emacs

1.15.2 Copy path of file at point


• Copy path of file at point.
(defun dired-copy-path ()
"In dired, copy file path to kill-buffer.
At 2nd time it copy current directory to kill-buffer."
(interactive)
(let (path)
(setq path (dired-file-name-at-point))
(if (string= path (current-kill 0 1)) (setq path (dired-current-directory)))
(message path)
(kill-new path)))

1.15.3 Paste a file from clibpboard


This command pastes a file which path is stored in clibpoard.
Usage:
1. Copy file from clibpoard with Emacs or from system's default file manager.
2. M-x dired-paste-file-from-clipboard
(defun dired-paste-file-from-clipboard ()
"Paste a file from clpboard to current directory."
(interactive)
(flet ((clipboard-get ()
(with-temp-buffer
(clipboard-yank)
(buffer-substring-no-properties
(point-min)
(point-max)))))
(copy-file (clipboard-get) ".")
(revert-buffer)))

1.15.4 Create empty file (touch)


• Create empty file at current directory opened in dired mode.
(defun dired-touch ()
"Creates empty file at current directory."
(interactive)
(append-to-file "" nil (read-string "New file: "))
(if (equal major-mode 'dired-mode)
(revert-buffer)))

1.15.5 Open multiple marked files


(defun dired-open-files (files)
"Open all marked files in dired mode with m.
Usage:
1. Mark the files with m
2. M-x dired-open-files"
(interactive
(list (dired-get-marked-files)) )
(mapc #'find-file files))

1.15.6 Close multiple marked files


(setq lexical-binding t)

(defun compose (fn1 fn2)


(let ((lexical-binding t))
(lambda (x)
(funcall fn2 (funcall fn1 x)))))

(defun dired-close-files (files)


(interactive (list (dired-get-marked-files)) )
(mapc (compose #'get-file-buffer #'kill-buffer) files))

1.15.7 Open a file with default system application   dired file open system


Usage. Select a file in dired mode and enter M-x dired-xdg

Function: xdg-open. Open any file with system's default application.


(defun xdg-open (filename)
"Open a file FILENAME with default system application.
This function is operating system independent."
(cl-case system-type

;;; Linux
(gnu/linux (let ((process-connection-type nil))
(start-process
"proc"
nil
;; Command
"xdg-open" (expand-file-name filename))))

;;; Free BSD OS


(gnu/kfreebsd (let ((process-connection-type nil))
(start-process
"proc"
nil
;; Command
"xdg-open" (expand-file-name filename))))

;; Mac OSX - (Not tested )


(darwing (start-process
"proc"
nil
;; Command
"open" (concat (expand-file-name filename))))

;; Windows 7, 8, 10 - Kernel NT
(windows-nt (start-process
"proc"
nil
;; Command
"cmd" "/C" "start" "" (expand-file-name filename)
))))

Function: dired-xdg
(defun dired-xdg ()
"Open file at point with systems' default app.
Usage: In the dired mode select a file and type M-x dired-xdg
to execute the file with the system default app.
"
(interactive)
(with-current-buffer
(xdg-open (dired-get-filename))))

1.15.8 Close all dired buffers


(defun dired-close-all ()
"Close all dired buffers."
(interactive)
(mapc (lambda (buf)
(if (equal (buffer-local-value 'major-mode buf)
'dired-mode)
(kill-buffer buf)))

(buffer-list)))

1.15.9 Browse bookmarked directories   dired directory helm browse


The function M-x dired-bookmarks opens a helm menu where the user can select its favorites
directories. It provides quick directory navigation.
(defvar dired-bookmarks-path-list
'("~"
"~/Desktop"
"~/Downloads"
"~/Documents"
"~/Documents/projects"
"~/Documents/wiki"
"/tmp"
;"/mnt/transfer"
"/var/log"
"/etc"
"/etc/init.d"
"~/.config"
"~/.local"
"~/.local/share"
"~/.emacs.d"
))

(defun dired-bookmarks ()
"Open a directory by selecting it in Helm menu."
(interactive)
(helm
:prompt "Bookmarks: "
:sources `((
(name . "Bookmark: ")
(candidates . dired-bookmarks-path-list)
(action . dired)
))))

1.15.10 Filter dired buffer by file extensions


Usage:
1. M-x dired/filter-extension
2. Enter the extensions to filter separated by space like: 'html js ccp'
3. It will only show files matching this extensions. To view all files type g.
(defun dired/filter-extension ()
"Filter dired buffer by file extensions.
Usage:
1. M-x dired/filter-extension
2. Enter the file extensions separated by space like: exe dll

It will only show files ending with extensions *.exe and *.dll.
To show all files of dired buffer again type 'g'."
(interactive)
(dired-mark-files-regexp
(mapconcat 'identity
(mapcar (lambda (ext) (format "\\.%s$" ext))
(split-string (read-string "Extension: ")))
"\\\|"
))
(dired-toggle-marks)
(dired-do-kill-lines))

The key (') quote can be used to invoke this command:


;; Filter files by extension
(define-key dired-mode-map "'" #'dired/filter-extension)

1.15.11 Filter dired buffer by regex


This command only displays files matching the given regex (Emacs' regex).
Example: By entering M-x dired/filter '\.pdf$' without quotes it will only show file names ending
with .pdf. To display all files again type 'g'.
(defun dired/filter ()
"Show only files which name matches a regex."
(interactive)
(dired-mark-files-regexp (read-regexp "Regex: "))
(dired-toggle-marks)
(dired-do-kill-lines))

1.15.12 Open directory at point with Microsoft Explorer in Windows OS.


(defun dired-exec-explorer ()
"In dired, execute Explorer"
(interactive)
(let (path)
(setq path (dired-file-name-at-point))
(setq path (replace-regexp-in-string "~" "c:/home" path))
(setq path (replace-regexp-in-string "/" "\\\\" path))
(message path)
;(kill-new path)
(start-process "explorer" nil "explorer" (concat "/select," path))))

1.16 Date Time


1.16.1 Overview
References:
• Time Parsing - GNU Emacs Lisp Reference Manual
• Time of Day - GNU Emacs Lisp Reference Manual

1.16.2 Function format-time-string


Format date and time:
ELISP> (format-time-string "%Y-%m-%d")
"2017-07-15"

ELISP> (format-time-string "%Y%m%d")


"20170715"
ELISP>

Unix time stamp (Number of seconds or microseconds since January first of 1970):
ELISP> (format-time-string "%s")
"1500103484"
ELISP>

1.16.3 Function current-time


ELISP> (current-time)
(22889 50074 486018 948000)

1.16.4 Function current-time-string


ELISP> (current-time-string)
"Sat Jul 15 04:26:27 2017"
ELISP>

1.16.5 Function float-time


ELISP> (float-time)
1500103652.678849
ELISP>

1.16.6 Function current-time-zone


ELISP> (current-time-zone)
(-10800 "-03")

ELISP>

1.17 Emacs Introspection

1.17.1 User init file


ELISP> user-init-file
"/home/arch/.emacs.d/init.el"

ELISP> (expand-file-name user-init-file)


"/home/arch/.emacs.d/init.el"

1.17.2 User Emacs Directory


ELISP> user-emacs-directory
"~/.emacs.d/"

ELISP> (expand-file-name user-emacs-directory)


"/home/arch/.emacs.d/"

1.17.3 Enviroment Variables

1.17.4 Get current Operating System

1.17.5 Test if Emacs is running in terminal or in window system


The variable window-system is the name of window system through which the selected frame is
displayed.
Its value is a symbol:
• nil for a termcap frame (a character-only terminal)
• 'x' for an Emacs frame that is really an X window
• 'w32' for an Emacs frame that is a window on MS-Windows display
• 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display
• 'pc' for a direct-write MS-DOS frame.
(defun test-window-system ()
(interactive)

(if window-system
(message "Running in Window System / GUI")
(message "Running in terminal ")
))

;; In GUI
;;-----------------------------
> (test-window-system) ;; M-x eval-print-last-sexp
"Running in Window System / GUI"

;; In Terminal
;;------------------------------
> (test-window-system) ;; M-x eval-print-last-sexp
"Running in terminal "

1.18 Web Browser   http web browser


1.18.1 Browse Url
Open http://www.yandex.com in the web browser
> (browse-url "http://www.yandex.com")

Function to open Yandex.com. Usage M-x open-yandex


(defun open-yandex ()
"Open the web site http://www.yandex.com."
(interactive)
(browse-url "http://www.yandex.com"))

1.18.2 Browser Url setting the web browser


Open url with firefox
(let ((browse-url-browser-function 'browse-url-firefox))
(browse-url "http://www.yandex.com"))

;; Or

;; Set browser permanently


(setq browse-url-browser-function 'browse-url-firefox)

Open url with chromium browser or chrome


(let ((browse-url-browser-function 'browse-url-chromium))
(browse-url "http://www.yandex.com"))

;;; Or

;; Set browser permanently


(setq browse-url-browser-function 'browse-url-chromium)

Open url with Emacs eww browser


(let ((browse-url-browser-function 'eww-browse-url))
(browse-url "http://www.yandex.com")

;;; Or

;; Set browser permanently


(setq browse-url-browser-function 'eww-browse-url)

1.18.3 Search Web sites with Emacs   web search url browser

1. Search google
Usage: M-x search-google
(require 'url-util)

(defun search-google ()
(interactive)
"Search www.google.ca."
(browse-url
(format "http://www.google.ca?gws_rd=ssl#q=%s"
(url-encode-url
(read-string "Google: ")))))

2. Search a specific url site with google


Usage:
• M-x search-hackernews-with-google
• M-x search-reddit-with-google
• M-x search-stackoverflow-with-gooogle
Usage: M-x search-google

(require 'url-util)

(defun search-google-url (url params)


(let ((google-url (format "site:%s %s" url params)))
(browse-url (format "http://www.google.ca?gws_rd=ssl#q=%s" (url-encode-
url google-url)))))

(search-google-url "https://news.ycombinator.com" "haskell production")

(defun search-hackernews-with-google ()
(interactive)
(search-google-url "https://news.ycombinator.com" (read-string "Hnews:
")))

(defun search-reddit-with-google ()
(interactive)
(search-google-url "https://www.reddit.com" (read-string "Reddit: ")))

(defun search-stackoverflow-with-google ()
(interactive)
(search-google-url "http://stackoverflow.com" (read-string "S.O Search:
")))

3. Search github
(require 'url-util)

(defun search-github ()
(interactive)
"Search www.google.ca"
(browse-url
(format "https://github.com/search?q=%s"
(url-encode-url
(read-string "Github Search: ")))))

4. Search gisthub
(require 'url-util)

(defun search-gisthub ()
"Search gisthub : http://gist.github.com.
Usage: M-x search-gisthub"
(interactive)
(browse-url
(format "https://gist.github.com/search?p=50&q=%s&ref=searchresults"
(url-encode-url
(read-string "Gisthub Search: ")))))

5. Open Emacs Web Manual


(defun open-emacs-manual ()
"Open Emacs online Manual.
Usage: M-x open-emacs-manual.
It opens the web site: https://www.gnu.org/software/emacs/manual"
(interactive)
(browse-url "https://www.gnu.org/software/emacs/manual/"))

6. Search words in Merrian Webster dictionary


(defun search/dictionary ()
"Search Merrian Webster Dictionary·"
(interactive)
(browse-url
(format "https://www.merriam-webster.com/dictionary/%s"
(url-encode-url
(read-string "Dictionary: ")))))

1.18.4 Browser Inside Emacs


Emacs Provides a built-in lightweight web browser eww browser that can be used to quick access web
sites in terminal or Emacs GUI.
Open a Url with eww-browser:
• M-x eww <url>
(eww-browse-url "http://m.reddit.com/r/emacs")

Open a html file with eww-browser


• M-x eww-open-file <file-name>

It is useful to view html documentation inside Emacs.


(eww-open-file "/some/html/file.html")

Key Bindings

Key Binding Description


C-h m Show all keybindings of eww-mode
q Quit eww browser
Return/Enter Open url at point
Tab Jump to next hyperlink
C-A i Jump to previous hyperlink
Key Binding Description
Space Scrow Down
Esc Scrow Up
w Copy page Url
l Go to previous page
n Got to next page
g Update/ Refresh
To load web sites faster use mobile url. Some suggestions:
Reddit
• http://m.reddit.com
• http://m.reddit.com/r/emacs
Google Search
• http://www.google.com/m?q=<query> - Country/Culture sensitive search
• http://www.google.ca/m?q=<query> - Country/Culture insensitive search, always
English.
Google News:
• http://www.gooogle.com/m/news - Country/Culure sensitive
• http://www.google.ca/m/news - Canada News
Arch Linux Wiki
• http://wiki.archlinux.org/index.php/Table_of_contents
Wikipedia
• http://en.m.wikipedia.org
Hackernews
• http://www.news.ycombinator.com
See the browser http request:
• http://www.httpbin.org/get

1.19 Http Requests   http request url network

1.19.1 Download File   http web download


(url-copy-file <url> <filename>)
(url-copy-file "http://www.httpbin.org/get" "/tmp/output")
(find-file "/tmp/output")

1.19.2 url-retrieve-synchronously   http web download sync
(url-retrieve-synchronously URL &optional SILENT INHIBIT-COOKIES)

Example:
(with-current-buffer (url-retrieve-synchronously "http://www.httpbin.org/get")
(buffer-substring-no-properties (point-min) (point-max)))

Output:
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 23 Sep 2016 23:44:21 GMT
Content-Type: application/json
Content-Length: 304
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip",
"Extension": "Security/Digest Security/SSL",
"Host": "www.httpbin.org",
"Mime-Version": "1.0",
"User-Agent": "URL/Emacs"
},
"origin": "179.176.152.199",
"url": "http://www.httpbin.org/get"
}

1.19.3 Download a file interactively   http web download file


This function downloads a file from the url copied to clipboard and then asks the user to which file the
data will be downloaded suggesting the file name extracted from the url.
This function updates the current buffer (revert buffer) if executed in a dired buffer (directory).
Testing the function:
• 1. Copy the url: https://raw.githubusercontent.com/nybbles/kaggle/master/train.csv
• 2. M-x download-url-to-file
• 3. View file in current directory. C-x d to open it.

Usage: M-x download-url-to-file


(defun download-url-to-file ()
"Download a file from a URL in the clibpoard.
This command asks the user for the url suggesting the url
stored in the clipboard and then asks the user for the file name
to be downloaded suggesting the file name extracted from the url.
"
(interactive)
(let*
;; Get the URL suggestion from clibpoard
((text (with-temp-buffer
(clipboard-yank)
(buffer-substring-no-properties (point-min)
(point-max))))
;; Ask the user to confirm the url
(url (read-string "Url: " text)))

(url-copy-file
url
;; Get file name.
(read-file-name "File name: "
(car (last (split-string url "/")))))

(when (equal major-mode 'dired-mode)


(revert-buffer))))

1.19.4 Download a file and display it on a buffer   http web buffer clipboard


This command reads an url from the user and download the file content and displays it on a buffer
without write a file to disk.
Example:
1. User copies the url: (file: iterator-theory.cs)
http://patterns.cs.up.ac.za/examples/ch9/iterator-theory.cs
2. User enters the command M-x download-code-view
3. It will suggest in a prompt the former url. User hit return.
4. It download the code and displays it on a buffer iterator-theory.cs
5. User enter the command. M-x csharp-mode that turns on the syntax hightlight.
(defun download-code-view ()
"Download a source code from url and displays it on a buffer."
(interactive)
(let* (
;; Get url from clipboard
(clipboard (with-temp-buffer
(clipboard-yank)
(buffer-substring-no-properties (point-min)
(point-max))))
;; Read url and suggesting clipboard
(url (read-string "Url: " clipboard))
(buf (url-retrieve-synchronously url))
;; Tries to extract the file name from url
(filename (car (last (split-string url "/"))))
(bufname (concat "*" filename "*"))
)
(switch-to-buffer buf)
;; Remove http header
(goto-char (point-min))
(re-search-forward "^$")
(delete-region (point) (point-min))
(kill-whole-line)
;; Remove \r characters or ^M
(replace-string (char-to-string 13) "")
;; Rename buffer to a better name
(with-current-buffer buf
(rename-buffer bufname))))

1.19.5 Http and Post Request   utils connections http


Source
(defun url-http-post (url args)
"Send ARGS to URL as a POST request."
(let (
(response-string nil)
(url-request-method "POST")
(url-request-extra-headers
'(("Content-Type" . "application/x-www-form-urlencoded")))
(url-request-data
(mapconcat (lambda (arg)
(concat (url-hexify-string (car arg))
"="
(url-hexify-string (cdr arg))))
args
"&")))
(switch-to-buffer
(url-retrieve-synchronously url))
(goto-char (point-min))
(re-search-forward "\n\n")
(setq response-string
(buffer-substring-no-properties (point) (point-max)))
(kill-buffer (current-buffer))
response-string))

(defun url-http-get (url args)


"Send ARGS to URL as a GET request."
(let (
(response-string nil)
(url-request-method "GET")
(url-request-data
(mapconcat (lambda (arg)
(concat (url-hexify-string (car arg))
"="
(url-hexify-string (cdr arg))))
args
"&")))
(switch-to-buffer
(url-retrieve-synchronously
(concat url "?" url-request-data)))
(goto-char (point-min))
(re-search-forward "\n\n")
(setq response-string
(buffer-substring-no-properties
(point) (point-max)))
(kill-buffer (current-buffer))
response-string))

ELISP> (princ (url-http-get "http://httpbin.org/get" nil))


{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip",
"Content-Length": "0",
"Extension": "Security/Digest Security/SSL",
"Host": "httpbin.org",
"Mime-Version": "1.0",
"User-Agent": "URL/Emacs"
},
"origin": "167.103.159.147",
"url": "http://httpbin.org/get"
}

ELISP> (princ (url-http-post "http://httpbin.org/post" '(("use" . "dummy") ("pass"


. "something else") ("code" . "pxyz0011213"))))
{
"args": {},
"data": "",
"files": {},
"form": {
"code": "pxyz0011213",
"pass": "something else",
"use": "dummy"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip",
"Content-Length": "48",
"Content-Type": "application/x-www-form-urlencoded",
"Extension": "Security/Digest Security/SSL",
"Host": "httpbin.org",
"Mime-Version": "1.0",
"User-Agent": "URL/Emacs"
},
"json": null,
"origin": "167.103.159.147",
"url": "http://httpbin.org/post"
}

1.20 Packages   package install library

1.20.1 Test if package is installed


If the package is installed returns t (true) and nil otherwise.
• (package-installed-p PACKAGE &optional MIN-VERSION)
> (package-installed-p 'helm-core)
t
1.20.2 Install a package if it is not installed

1.20.3 Install a single-file package from URL


This command install a single-file elisp package from a given URL to source file.
Usage:
1. Copy the url of the package file to be installed like http://mumble.net/~campbell/emacs/paredit-
beta.el from EmacsWiki:Par Edit.
2. Type M-x package-install-url It will ask to confirm the URL. Then type return and the package
will be installed.
To find where the package was intalled type M-x find-library <library-name>.
(defun package-install-url ()
"Install a single-file package *.el file from Url."
(interactive)
(let* (
;; Suggest the URL stored in the clipboard
(clipboard (with-temp-buffer
(clipboard-yank)
(buffer-substring-no-properties (point-min) (point-max))))
;; Ask the user to confirm the url
(url (read-string "Url: " clipboard))
)

(with-current-buffer (url-retrieve-synchronously url)


(goto-char (point-min))
(re-search-forward "^$")
(delete-region (point) (point-min))
(kill-whole-line)
(package-install-from-buffer))))

1.21 Helm Snippets   framework library helm

1.21.1 Switch between buffers in same directory


Usage: M-x buffer/switch-in-directory
This command switches between buffer with files that are in current directory.
(defun buffer/with-file-in-directory-p (directory buf)
"Check if a buffer has file associated and is is in DIRECTORY.
Parameters:
- directory string - root directory
- buf buffer object - buffer object"
(and (buffer-file-name buf) ;; check if buffer has a file associated
(string-prefix-p (expand-file-name directory)
(expand-file-name (buffer-file-name buf)
))))

(defun buffer/switch-in-directory ()
"Switch between buffers in same directory."
(interactive)
(helm
:prompt "Buffer switch: "
:sources `((
(name . "Dir: ")
(candidates . ,(mapcar
(lambda (b) (cons (buffer-name b) b))
;; filter buffers not in this directory (code
bellow)
(remove-if-not (lambda (b)
(buffer/with-file-in-directory-p
(or (file-name-directory
(buffer-file-name))
default-directory
)
b
))
(buffer-list)
)))
(action . switch-to-buffer)
))))

1.21.2 Browser Recent files


Usage: M-x helm-recent-files
(require 'helm)

(defun helm-recent-files ()
(interactive)
(helm
:prompt "File: "
:sources `((
(name . "File: ")
(candidates . ,recentf-list)
(action . find-file)
))))
1.21.3 Browser Recent directories
Usage M-x helm-recent-dirs
(require 'helm)

(defun unique (xs)


"Remove repeated elements from list xs
Example:
> (unique '(x y a b 21 21 10 21 x y a ))
(x y a b 21 10)."
(let ((result nil))
(dolist (x xs)
(if (not (member x result))
(push x result)))
(reverse result)))

(defun helm-recent-dirs ()
(interactive)
(helm
:prompt "Dir: "
:sources `((
(name . "Dir: ")
(candidates . (lambda ()
(unique
(map #'file-name-directory recentf-list))))
(action . dired)))))

1.21.4 Launch ansync shell command with helm


This piece of code gets all executables in the $PATH variable and searche for one that matches the user
input and then launches it. It is useful to launch applications without block Emacs.
Usage: M-x helm-laucher
(defun get-executables ()
"Returns a list of all files available in the directories of the $PATH variable."
(apply #'append
(mapcar (lambda (p) (directory-files p t))
(remove-if-not #'file-exists-p
(split-string (getenv "PATH") ":")))))

(defun run-async (&optional command)


"Run a shell command in asynchronous mode.
It doesn't block Emacs while the command is running.
Usage: (run-async \"python -m http.server\")
M-x run-async -> User enters a command."
(interactive)
(apply #'start-process
`(
"proc-any" ;; We don't care about the application name
nil ;; Don't name the buffer
,@(split-string-and-unquote
(if command
command
(read-string "Command: " )
)))))
(defun run-async-lst (&rest commands)
"Run a shell command in asynchronus mode, not blocking Emacs.
Usage: > (run-async-lst <program> <argument 1> <agurment2> ...)
Example: > (run-async \"thunar\" \"/usr/share/applications\")"
(apply #'start-process
`(
"dontcare" ;; We don't care about the application name
nil ;; Don't name the buffer
,@commands
)))

(defun helm-launcher ()
"Launches apps available in $PATH without blocking Emacs.
Usage M-x heml-launcher"
(interactive)
(let ((data (mapcar (lambda (p)
(cons (file-name-nondirectory p)
p
))
(get-executables)
)))
(helm
:prompt "Shell: "
:sources `((
(name . "Shell: ")
(candidates . ,data)
(action . run-async)
)))))

1.21.5 Switch between buffers associated with files


Switch between buffers associated with files.
(defun switch-file ()
"Switch between buffers that are associated with files.
Usage: M-x switch file."
(interactive)
(let ((data
(mapcar (lambda (b)
(cons (buffer-file-name b) b ))
(remove-if-not #'buffer-file-name (buffer-list)))))
(helm
:prompt "Buffer: "
:sources `((
(name . "File Buffers")
(candidates . ,data)
(action . switch-to-buffer)
)))))

1.21.6 Switch between Emacs major modes


(defun helm-switch-mode ()
"Switch between all major programming modes available in Emacs.
Usage: M-x helm-switch-mode."
(interactive)
(cl-flet ((unique (xs)
(let
((result nil))
(dolist (x xs)
(if (not (member x result))
(push x result)))
(reverse result))))
(helm
:prompt "Mode: "
:sources `((
(name . "Emacs Major Modes")
(candidates . ,(unique (mapcar #'symbol-name
(remove-if-not #'symbolp
(mapcar #'cdr auto-mode-
alist)))))
(action . ,(lambda (m) (funcall (intern-soft m)))))))))

1.21.7 Open a list of web sites


(setq helm-url-default-url-list
'(
("google" . "http://www.google.ca")
("yandex" . "http://www.yandex.com")
("reddit" . "http://www.reddit.com")
("/r/haskell". "http://www.reddit.com/r/haskell")
("/r/emacs" . "http://www.reddit.com/r/emacs")
("/r/csharp" . "http://www.reddit.com/r/csharp")
))

(defun helm-web ()
(interactive)
(helm
:prompt "Web Site: "
:sources `((
(name . "Bookmarks")
(candidates . helm-url-default-url-list)
(action . (lambda (c) (browse-url (cdr c))) )
))))
1.21.8 Interface Makefile
This command extracts the build tasks from a Makefile and shows it as a helm menu where the user
can select the task to be executed. It will be run as a asynchronous process.
Usage: M-x helm-make
Version1:
;; Taken from: http://emacs.stackexchange.com/questions/7148/get-all-regexp-
matches-in-buffer-as-a-list
(defun re-seq (regexp string)
"Get a list of all regexp matches in a string"
(save-match-data
(let ((pos 0)
matches)
(while (string-match regexp string pos)
(push (match-string 0 string) matches)
(setq pos (match-end 0)))
matches)))

(defun helm-make ()
(interactive)
(let ((tasks
(re-seq "^\\w+"
(with-temp-buffer
(insert-file "Makefile")
(buffer-substring-no-properties
(point-min)
(point-max))))))
(helm
:prompt "Makefile task: "
:sources `((
(name . "Task")
(candidates . ,tasks)
(action . (lambda (task)
(start-process "make"
"*make*"
"make" task
))))))
(switch-to-buffer "*make*")))

Version2: Remove dependency re-seq.


(defun helm-make2 ()
(interactive)
(flet ((re-seq2 (regexp string) (save-match-data
(let ((pos 0)
matches)
(while (string-match regexp string pos)
(push (match-string 0 string) matches)
(setq pos (match-end 0)))
matches))))
(let ((tasks (re-seq2 "^\\w+"
(with-temp-buffer
(insert-file "Makefile")
(buffer-substring-no-properties
(point-min)
(point-max)
)))))
(helm
:prompt "Makefile task: "
:sources `((
(name . "Task")
(candidates . ,tasks)
(action . (lambda (task)
(start-process "make"
"*make*"
"make" task
))))))
(switch-to-buffer "*make*"))))

Example: Assuming that the current directory has the Makefile with content. The command M-x helm-
make will show the tasks all, html, browse and clean.
all: html

html:
mkdir -p dist
emacs --batch -q -l build.el --kill
mv dist/README.html dist/index.html
cp -r -v images dist/images
cp -r *.org dist/

browse:
firefox dist/index.html

clean:
rm -rf dist/*.html dist/*.html~

1.22 Persistence

1.22.1 Save and Reload Current Session


Interactive Developement
ELISP> (defun file-contents (filename)
(interactive "fFind file: ")
(with-temp-buffer
(insert-file-contents filename)
(buffer-substring-no-properties (point-min) (point-max))))
file-contents
ELISP>

ELISP> (defun write-file (filename content)


(append-to-file content nil filename))
write-file
ELISP>
ELISP> (remove-if 'null (mapcar 'buffer-file-name (buffer-list)))
("/home/tux/.emacs.d/init.el" "/sudo:root@localhost:/etc/host.conf")

ELISP> (setq session-file "~/.emacs.d/lastsession.el")


"~/.emacs.d/lastsession.el"
ELISP>

ELISP>
ELISP> (format "(setq last-session-files '%S)" (remove-if 'null (mapcar 'buffer-
file-name (buffer-list))))
"(setq last-session-files '(\"/home/tux/.emacs.d/init.el\" \"/sudo:root@localhost:/
etc/host.conf\"))"

ELISP> (setq code (format "(setq last-session-files '%S)" (remove-if 'null (mapcar
'buffer-file-name (buffer-list)))))
"(setq last-session-files '(\"/home/tux/.emacs.d/init.el\" \"/sudo:root@localhost:/
etc/host.conf\"))"
ELISP>

ELISP> (setq session-file "~/.emacs.d/lastsession.el")

ELISP> (delete-file session-file)


nil

ELISP> (write-file session-file code)


nil
ELISP>

ELISP> (file-contents session-file)


"(setq last-session-files '(\"/home/tux/.emacs.d/init.el\" \"/sudo:root@localhost:/
etc/host.conf\"))"
ELISP>

ELISP> (load-file session-file)


t
ELISP> last-session-files
("/home/tux/.emacs.d/init.el" "/sudo:root@localhost:/etc/host.conf")

;;; Open All files defined in Last Session


ELISP>
ELISP> (mapcar 'find-file last-session-files)
(#<buffer init.el> #<buffer host.conf>)

ELISP>

Joining Everything
File: sessions.el
(setq session-file "~/.emacs.d/lastsession.el")

(defun write-file (filename content)


(append-to-file content nil filename))

(defun make-session-code ()
(interactive)
(format "(setq last-session-files '%S)" (remove-if 'null (mapcar 'buffer-file-
name (buffer-list)))))

(defun save-session ()
"Save Current Session"
(interactive)
(when (file-exists-p session-file) (delete-file session-file))
(write-file session-file (make-session-code)))

(defun load-session ()
(interactive)
(load-file session-file)
(mapcar 'find-file last-session-files)
)

(message "Reloaded")

To save all bufffers with files:


M-x load-file ;; Enter session.el
M-x save-session

To reload the files save in the seesion enter:


M-x load-file ;; Enter session.el
M-x load-session ;; All previous files in the session
;; saved will be opened

1.22.2 Save and Restore Current Window Configuration


Press <F7> to save the curren window configuration and <F8> to restore. The functions can also be
executed with A-x save-view or A-x restore-view.
(defun save-view ()
"Save current window configuration"
(interactive)
(setq winconf (current-window-configuration))
(message "View Saved - Press to restore"))

(defun restore-view ()
"Restore saved window configuration"
(interactive)
(set-window-configuration winconf)
(message "View loaded"))

(global-set-key (kbd "<f7>") #'save-view)


(global-set-key (kbd "<f8>") #'restore-view)

1.23 Non categorized

1.23.1 Save the scratch buffer and reload every Emacs startup
Saves the scratch buffer to a file every times Emacs is closed.
Source: scratch.el
(setq scratch-buffer-file "~/.emacs.d/scratch.el")

(setq initial-scratch-message "") ;initial message


(add-hook 'kill-emacs-hook 'scratch-save) ;
(add-hook 'window-setup-hook 'scratch-resume);

;; window-setup-hook
;; @see info 38.1.1 Summary: Sequence of Actions at Startup
(add-hook 'kill-buffer-hook; *scratch*
(lambda ()
(if (equal (buffer-name) "*scratch*") (scratch-save))))

(add-hook 'after-save-hook
(lambda ()
(unless (get-buffer "*scratch*") (scratch-resume))))

(defun scratch-save ()
(let ((buf (get-buffer "*scratch*")))
(when buf
(set-buffer buf)
(write-file scratch-buffer-file)
(ignore-errors (kill-buffer "scratch.el")))))

(defun scratch-resume ()
"*scratch* "
(interactive)
(set-buffer (get-buffer-create "*scratch*"))
(funcall initial-major-mode)
(insert-file-contents scratch-buffer-file nil nil nil t)

(ignore-errors (kill-buffer ".scratch")))

1.23.2 Code Navigation with Occur   edit


The function occur is useful for code navigation and scan code statements, this function is invoked by
M-x occur.
Examples:
The function python/scan-functions will scan for all lines that starts with def statement in a Python
code and show the matching lines in the right side.
(defun python/scan-functions ()
(interactive)
(split-window-horizontally)
(occur "def"))

Example:
It can also be useful to Scan code tags like: @FIXME, @TODO, @README, @NOTE. This fuction
can be excuted by typing: M-x scan-code-tags

Example:
(defun scan-code-tags ()
"Scan code tags: @TODO: , @FIXME:, @BUG:, @NOTE:."
(interactive)
(split-window-horizontally)
(occur "@FIXME:\\|@TODO:\\|@BUG:\\|@NOTE:"))
1.23.3 Quick edit and reload Emacs Configuration File.   elisp customization
It is useful to quick edit and reload ~/emacs.d/init.el without restart emacs. Those functions can be put
in the init.el file.
;; Usage: M-x reload-init-file
;;
(defun reload-init-file ()
"Reload init.el file."
(interactive)
(load user-init-file)
(message "Reloaded init.el OK."))

;; Usage: M-x open-init-file


;;
(defun open-init-file ()
(interactive)
(find-file user-init-file))

1.23.4 Refresh / Revert buffer without confirmation.


Source: http://www.emacswiki.org/emacs-en/download/misc-cmds.el
(defun refresh ()
"Revert buffer without confirmation."
(interactive)
(revert-buffer t t))

Usage:
#+ENDSRC M-x refresh #+ENDSRC

1.23.5 Create a menu with all color themes available


Using Eval
Copy and paste the code below to the scratch buffer and enter M-x eval-buffer. This code can also be
put in ~/emacs.d/init.el, in the config file.
(defun eval-string (str) (eval (read str)))

(defun make-menu-rows ()
(mapcar
(lambda (x)
(format "[\"%s\" (load-theme '%s)]" (symbol-name x) (symbol-name x) ))
(custom-available-themes)))

(defun make-color-menu-code ()
(format
"
(easy-menu-define djcb-menu global-map \"Color Themes\"
'(\"Color Themes\"
%s
)
)
"
(mapconcat 'identity (make-menu-rows) "\n")))

;;
;; "Eval is evil". It must be avoided, because, it is hard to refactor,
;; hard to debug and vulnerable to code injection on Web Apps, so a better
;; way to write it is to use Elisp macros.
;;
;; @DONE: Change eval-string to an Elisp macro.
;;
(eval-string (make-color-menu-code))
Using Macros
Developement:
ELISP> (custom-available-themes)
(cyberpunk adwaita deeper-blue dichromacy leuven light-blue manoj-dark misterioso
tango-dark tango tsdh-dark tsdh-light wheatgrass whiteboard wombat)

ELISP> (mapcar
(lambda (sym) `[,(symbol-name sym) (load-theme (quote ,sym))])
(custom-available-themes)
)
(["adwaita"
(load-theme 'adwaita)]
["deeper-blue"
(load-theme 'deeper-blue)]
["dichromacy"
(load-theme 'dichromacy)]
["leuven"
(load-theme 'leuven)]
["light-blue"
(load-theme 'light-blue)]
["manoj-dark"
(load-theme 'manoj-dark)]
["misterioso"
(load-theme 'misterioso)]
["tango-dark"
(load-theme 'tango-dark)]
...

ELISP> (defun make-menu-rows ()


(mapcar
(lambda (sym) `[,(symbol-name sym) (load-theme (quote ,sym))])
(custom-available-themes)))
make-menu-rows
ELISP>
ELISP> (make-menu-rows)
(["adwaita"
(load-theme 'adwaita)]
["deeper-blue"
(load-theme 'deeper-blue)]
["dichromacy"
(load-theme 'dichromacy)]
["leuven"
(load-theme 'leuven)]
...
ELISP> `(easy-menu-define djcb-menu global-map "Color Themes"
'("Color Themes"
,@(make-menu-rows)))
(easy-menu-define djcb-menu global-map "Color Themes"
'("Color Themes"
["adwaita"
(load-theme 'adwaita)]
["deeper-blue"
(load-theme 'deeper-blue)]
["dichromacy"
(load-theme 'dichromacy)]
["leuven"
(load-theme 'leuven)]
["light-blue"
(load-theme 'light-blue)]
...

;;; Now execute the generated code, the menu will pop up.
;;;

ELISP> (eval `(easy-menu-define djcb-menu global-map "Color Themes"


'("Color Themes"
,@(make-menu-rows))))
nil

Final code
(defun make-menu-rows ()
(mapcar
(lambda (sym) `[,(symbol-name sym) (load-theme (quote ,sym))])
(custom-available-themes)))

(defmacro make-color-menu ()
`(easy-menu-define djcb-menu global-map "Color Themes"
'("Color Themes"
,@(make-menu-rows))))

(make-color-menu)

;;;;; Or copy and paste the following block on IELM shell

(progn
(defun make-menu-rows ()
(mapcar
(lambda (sym) `[,(symbol-name sym) (load-theme (quote ,sym))])
(custom-available-themes)))

(defmacro make-color-menu ()
`(easy-menu-define djcb-menu global-map "Color Themes"
'("Color Themes"
,@(make-menu-rows))))
(make-color-menu))

;;;; Testing the macro expansion

ELISP> (macroexpand '(make-color-menu))


(progn
(defvar djcb-menu nil "Color Themes")
(easy-menu-do-define 'djcb-menu global-map "Color Themes"
'("Color Themes"
["adwaita"
(load-theme 'adwaita)]
["deeper-blue"
(load-theme 'deeper-blue)]
["dichromacy"
(load-theme 'dichromacy)]
["leuven"
(load-theme 'leuven)]
["light-blue"
(load-theme 'light-blue)]
...

2 IELM - Inferior Emacs Lisp Mode

2.1 Change Prompt


Change the default IELM prompt "ELISP> " to "> ".
(setq ielm-prompt "> ")

2.2 Clear IELM shell


Clear IELM buffer. Usage: M-x ielm/clear
(defun ielm/clear ()
"Clear IELM buffer."
(interactive)
(with-current-buffer "*ielm*"
(let ((inhibit-read-only t))
(erase-buffer))))

2.3 Send Region to IELM


Send selected text (region) to IELM and print the output.
(defun ielm/send-region ()
(interactive)
(let ((text (buffer-substring-no-properties (region-beginning)
(region-end))))
(with-current-buffer "*ielm*"
(insert text)
(ielm-send-input))))
2.4 Set other window's buffer as working buffer
Usage: M-x ielm-select-buffer-other-window
(defun ielm-select-buffer-other-window ()
"Select other window' buffer as IELM's working buffer."
(interactive)
(let ((buf (save-window-excursion
(other-window 1)
(current-buffer))))
(ielm-change-working-buffer buf)
(ielm-print-working-buffer)))

2.5 Start IELM in other window setting the working buffer to current buffer
This command starts IELM in other window setting the working buffer to current buffer. It allows the
user to manipulate the current buffer.
Usage: M-x ielm-this-buffer
(defun ielm-this-buffer ()
"Start IELM in other window with current buffer set to current windows' buffer."
(interactive)
(let ((buf (current-buffer)))
(ielm-other-window)
(ielm-change-working-buffer buf)
(ielm-print-working-buffer)))

2.6 Launch IELM in other frame


Usage: M-x ielm-other-frame
(defun ielm-other-frame ()
"Launch IELM in other frame."
(interactive)
(with-selected-frame (make-frame)
(ielm)))

3 Emacs Server and Client


See also:
• https://www.emacswiki.org/emacs/EmacsClient
• https://www.emacswiki.org/emacs/EmacsAsDaemon
• How I Use Emacs - mjwall.com
• Running Multiple Emacs Daemons on a Single System
• Running emacs as a daemon with systemd
• http://emacs-fu.blogspot.com.br/2009/02/emacs-daemon.html
• https://wiki.archlinux.org/index.php/Emacs
• Doing worker processing with EmacsLisp
• Packages for Emacs Programmers

4 Org-mode
Moved to: org-mode.html

5 Selected Gists and Source Codes

5.1 Gists
• extract archives from eshell
• garaud/pipe-to-emacs.py - Pipe to Emacs: Insert a result from an UNIX command into a new
Emacs buffer
• dvnmk/process - Play youtube playlist using Emacs + mpv player.
• TikhonJelvis/epage - "A little pager script I wrote that calls out to emacsclient."
• Elisp code to create a rails console

5.2 Source Codes


• https://www.emacswiki.org/emacs/download/install-elisp.el
Created: 2018-07-26 Thu 07:42
Emacs 25.3.1 (Org mode 8.2.10)
Validate
Elisp Cookbook
This page contains snippets of code that demonstrate basic EmacsLisp programming operations in the
spirit of the O’Reilly cookbook series of books. For every task addressed, a worked-out solution is
presented as a short, focused, directly usable piece of code.
All this stuff can be found elsewhere, but it is scattered about in libraries, manuals, etc. It would be
helpful to have here in one spot.
These recipes should be pastable into the *scratch* buffer so that users can hit ‘C-j’ and evaluate
them step by step.
There’s going to be some overlap with CategoryCode, obviously. Just link to more elaborate pages
when appropriate. Should this page grow too large, we’ll split it up later.
1. Strings
1. Strings vs buffer text
2. Substrings
3. starts-with and ends-with predicates
4. Processing characters
5. Trim whitespace
6. Splitting strings
7. Joining strings
8. Serialization
9. Formatting
2. Killing text
1. Delete region
2. Delete line
3. Delete line backwards
4. Delete line to next line
5. Delete whole line
6. Delete word
7. Delete sentence
3. Numbers
1. Test whether a string represents a number
2. String to number
3. Random numbers
4. Put commas in numbers
5. Increment numbers
6. Dates and times
1. Today's date
2. Formatting dates
3. Conversions
4. Pattern matching
1. Finding
2. Verifying
3. Search and replace
4. Search and do something with match
5. Extracting submatches from a regex match
6. Mapping with a regex
7. Finding all the strings that match
5. Code Comments
6. Sequences
1. Lists
2. Association lists
3. Vectors
1. Convert vector to list
7. Hash tables
1. Storing and retrieving keys and values
2. Sorting keys
8. Files
1. Read
2. Filter
3. Write
4. Input and output (I/O)
5. Searching within a File
6. Locking
7. Stat
8. Deleting
9. Copy, move and rename
10.Copy the buffer filename for yanking
9. Directories
1. Listing
2. Recursion
3. Traversing
4. Path splitting
10.Processes
1. Running a program
2. Handling signals
11.Sockets
1. Tcp client
2. Tcp server
12.Keys
1. Call function bound to key
2. Documenting key binding to lambda
13.Test code

Strings
The empty string (zero-length string, null string, …):
(zerop (string-match "" "")) ;; O(n)
==> t

(string-equal "" "") ;; O(n)?


==> t

(equal "" "") ;; O(n)?


==> t

(zerop (length "")) ;; O(1)


==> t

As a (very minor) space and performance optimization, starting with Emacs 23, Emacs keeps an
interned copy of the empty string as a single object
(eq "" "") ;; O(1)
==> t ; nil prior to Emacs 23

(eq "" (purecopy ""))


==> t ; nil prior to Emacs 23

(eq "" (propertize "" 'face 'italic))


==> t ; nil prior to Emacs 23

Strings vs buffer text


While it is quite common in other programming languages to work on strings contained in variables, in
Emacs it is also common to work on text in buffers.

Substrings
(substring "abcdefg" 0 3)
==> "abc"
(substring "abcdefg" -3 -1)
==> "ef"

The TO argument is optional:


(substring "abcdefg" -3)
==> "efg"

Buffers:
(with-temp-buffer (insert "abcdefg") (buffer-substring 2 4))
==> "bc"

starts-with and ends-with predicates


Standard functions (version 24.4):
(string-prefix-p "bull" "bulldozer") ; optional ignore case argument too
==> t

(string-suffix-p "dozer" "bulldozer") ; optional ignore case argument too


==> t

Custom functions:
(defun string/ends-with (s ending)
"Return non-nil if string S ends with ENDING."
(cond ((>= (length s) (length ending))
(let ((elength (length ending)))
(string= (substring s (- 0 elength)) ending)))
(t nil)))

(defun string/starts-with (s begins)


"Return non-nil if string S starts with BEGINS."
(cond ((>= (length s) (length begins))
(string-equal (substring s 0 (length begins)) begins))
(t nil)))

Faster, simpler:
(defun string/ends-with (string suffix)
"Return t if STRING ends with SUFFIX."
(and (string-match (rx-to-string `(: ,suffix eos) t)
string)
t))

The first argument to rx-to-string `(: ,suffix eos) is a regular expression in sexp form. The
help page for “rx” elucidates the syntax:
(: SEXP1 SEXP2 ...)
matches what SEXP1 matches, followed by what SEXP2 matches, etc.

,suffix is SEXP1 and eos is SEXP2 '(: suffix eos) would create a list of three elements:
The symbol named “:”, the symbol named “suffix”, and the symbol named “eos”. But that’s not what
this function wants. It wants the value of the symbol named “suffix”, not the symbol itself. ` is special
syntax (note the backtick, not just tick) that allows some things in the list to be preceded by a comma,
which are then evaluated. `(: ,suffix eos) is convenience syntax for (list ': suffix
'eos). The only symbol that is evaluated is suffix. Because there is no , before : or eos, both : and eos
are not evaluated. Symbols are not evaluated by default in the `( … ) syntax and require a , if you want
them to be evaluated. Thanks to <forcer> on #emacs-beginners irc channel for the explanation.
(defun string/starts-with (string prefix)
"Return t if STRING starts with prefix."
(and (string-match (rx-to-string `(: bos ,prefix) t)
string)
t))

Processing characters
Reversing a string:
(defun string/reverse (str)
"Reverse the str where str is a string"
(apply #'string
(reverse
(string-to-list str))))

See CharacterProcessing and StringModification. See tr for an example mixing strings and characters.
Looking at characters in a temporary buffer:
(with-temp-buffer
(insert "abcdefg")
(goto-char (point-min))
(while (not (= (char-after) ?b)) (forward-char))
(point))
==> 2

Trim whitespace
Trim whitespace from the end of a string:
(setq test-str "abcdefg ")
(when (string-match "[ \t]*$" test-str)
(message (concat "[" (replace-match "" nil nil test-str) "]")))

Trim whitespace from a string with a Perl-like chomp function:


(defun chomp (str)
"Chomp leading and tailing whitespace from STR."
(while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'"
str)
(setq str (replace-match "" t t str)))
str)

Let’s not overcomplicate matters:


(defun chomp-end (str)
"Chomp tailing whitespace from STR."
(replace-regexp-in-string (rx (* (any " \t\n")) eos)
""
str))
(defun chomp (str)
"Chomp leading and tailing whitespace from STR."
(replace-regexp-in-string (rx (or (: bos (* (any " \t\n")))
(: (* (any " \t\n")) eos)))
""
str))

Splitting strings
See SplitString.

Joining strings
Use ‘mapconcat’ to join strings, interpolating a separator string and possibly transforming each
string before joining.
For no transformation (‘identity’), use this:
(mapconcat 'identity '("" "home" "alex " "elisp" "erc") "/")
==> "/home/alex /elisp/erc"

If you have an Emacs version greater than 25.3 then you can alternatively use ‘string-join’ for
that simple case:
(string-join '("foo" "bar" "baz") ", ")
==> "foo, bar, baz"

(‘string-join’ is just ‘mapconcat’ with ‘identity’ for the transformation.)

For the even simpler case where you have no separator (it is "", you can just use ‘concat’ or
‘format’:
(concat "hello, " "world")
==> "hello, world"

(format "%s%s" "hello, " "world")


==> "hello, world"

(format "%s, %s" "hello" "world")


==> "hello, world"

Serialization
Convert forms to strings using ‘prin1-to-string’, then convert back from a string using
‘read’.
(length (read (prin1-to-string (make-list 1000000 '(x)))))
==> 1000000
(read (prin1-to-string "Hello World!"))
==> "Hello World!"

This works only in the simplest cases. Unfortunately, it doesn’t work for all EmacsLisp data types.
(read (prin1-to-string (make-hash-table))) ;; Error before Emacs 23.
==> #s(hash-table size 65 test eql rehash-size 1.5 [...] data ())

(read (prin1-to-string (current-buffer)))


==> Lisp error: (invalid-read-syntax "#")

Formatting

Killing text
As the ElispManual says, “Most of the kill commands are primarily for interactive use […] When you
need to delete text for internal purposes within a Lisp function, you should normally use deletion
functions, so as not to disturb the kill ring contents.”
The following mimic the ‘kill-’ commands but without disturbing the kill ring. To make them kill,
use ‘kill-region’ instead of ‘delete-region’.

Delete region
The Lisp equivalent of ‘kill-region’ (‘C-w’) but without kill-ring side effects::
(delete-region (region-beginning) (region-end))

According to the ElispManual, “Few programs need to use the ‘region-beginning’ and
‘region-end’ functions.” This is because Lisp code should not rely on nor “alter the mark unless
altering the mark is part of the user-level functionality of the command. (And, in that case, this effect
should be documented.) To remember a location for internal use in the Lisp program, store it in a Lisp
variable. For example: […]”

Delete line
The equivalent of ‘kill-line’ (‘C-k’) but without kill-ring side effects:
(let ((beg (point)))
(forward-line 1)
(forward-char -1)
(delete-region beg (point)))

Alternatively, replacing the ‘let’ with ‘progn’.


(delete-region (point) (progn (forward-line 1)
(forward-char -1)
(point)))
Or just: (delete-region (point) (line-end-position))

The examples with ‘forward-line’ are shown for comparison with other examples, below.

Delete line backwards


The equivalent of killing the line backwards (‘C-0 C-k’) but without kill-ring side effects:
(let ((beg (point)))
(forward-line 0)
(delete-region (point) beg))

Alternatively, replacing the ‘let’ with ‘progn’.


(delete-region (progn (forward-line 0) (point))
(point))

Or just: (delete-region (line-beginning-position) (point))

Delete line to next line


The equivalent of killing the line and the newline (‘C-1 C-k’) but without kill-ring side effects:
(let ((beg (point)))
(forward-line 1)
(delete-region beg (point)))

Alternatively, replacing the ‘let’ with ‘progn’.


(delete-region (point) (progn (forward-line 1) (point)))

Delete whole line


The equivalent of ‘kill-whole-line’ (‘C-S-DEL’) but without kill-ring side effects:
(let ((beg (progn (forward-line 0)
(point))))
(forward-line 1)
(delete-region beg (point)))

Alternatively, replacing the ‘let’ with ‘progn’.


(delete-region (progn (forward-line 0) (point))
(progn (forward-line 1) (point)))

Or just:
(delete-region (line-beginning-position)
(line-end-position))

Delete word
The equivalent of ‘kill-word’ (‘M-d’) but without kill-ring side effects:
(let ((beg (point)))
(forward-word 1)
(delete-region beg (point)))

Alternatively, replacing the ‘let’ with ‘progn’.


(delete-region (point) (progn (forward-word 1) (point)))

Delete sentence
The equivalent of ‘kill-sentence’ (‘M-k’) but without kill-ring side effects:
(let ((beg (point)))
(forward-sentence 1)
(delete-region beg (point)))

Alternatively, replacing the ‘let’ with ‘progn’.


(delete-region (point) (save-excursion
(forward-sentence 1)
(point)))

Numbers
Test whether a string represents a number
(defun string-integer-p (string)
(if (string-match "\\`[-+]?[0-9]+\\'" string)
t
nil))

(string-integer-p "1234")
==> t

(string-integer-p "x1234")
==> nil

(string-integer-p "3.141592653589793")
==> nil

(defun string-float-p (string)


(if (string-match "\\`[-+]?[0-9]+\\.[0-9]*\\'" string)
t
nil))

(string-float-p "1234")
==> nil

(string-float-p "3.141592653589793")
==> t

(string-float-p ".1")
==> nil
(string-float-p "1.")
==> t

String to number
The following example is for instruction. Normally standard function ‘string-to-number’ would
be used.
(defun decimal-number (string)
(let ((n (string-to-number string)))
(save-match-data
(if (and (not (zerop n))
(string-match "\\`\\s-*0+\\.?0*\\s-*\\'" string))
n
nil))))

(decimal-number "536870911")
==> 536870911

(decimal-number "536870912")
==> 536870912.0

(decimal-number "3.141592653589793")
==> 3.141592653589793

(decimal-number "042")
==> 42

(decimal-number " 0 ")


==> 0

(decimal-number "000")
==> 0

(decimal-number "0.0")
==> 0.0

Random numbers
(random 2) ;coin toss (0 or 1)
(+ (random 6) 1) ;dice

Put commas in numbers


(defun group-number (num &optional size char)
"Format NUM as string grouped to SIZE with CHAR."
;; Based on code for `math-group-float' in calc-ext.el
(let* ((size (or size 3))
(char (or char ","))
(str (if (stringp num)
num
(number-to-string num)))
;; omitting any trailing non-digit chars
;; NOTE: Calc supports BASE up to 36 (26 letters and 10 digits ;)
(pt (or (string-match "[^0-9a-zA-Z]" str) (length str))))
(while (> pt size)
(setq str (concat (substring str 0 (- pt size))
char
(substring str (- pt size)))
pt (- pt size)))
str))

(group-number 299792458)
==> "299,792,458"
(group-number "149597870691" 4 " ")
==> "1495 9787 0691"

Increment numbers
See IncrementNumber.

Dates and times


Today's date
(defun today-is ()
"Display current time."
(interactive)
(message (format-time-string "Today is %Y-%m-%d %T")))

See InsertingTodaysDate.

Formatting dates
Use the function ‘format-time-string’ which is a build in function in both Emacsen and works
like ‘strftime’:
;; Year-Month-Day:
(insert (format-time-string "%Y-%m-%d"))
;; Hour:Minutes:Seconds
(insert (format-time-string "%H:%M:%S"))

Conversions
Read a date from a string.
(let ((time (date-to-time "Tue, 27-Sep-83 12:35:59 EST")))
(set-time-zone-rule t) ;; Use Universal time.
(prog1 (format-time-string "%Y-%m-%d %T UTC" time)
(set-time-zone-rule nil))) ;; Reset to default time zone.
==> "1983-09-27 17:35:59 UTC"

Decode a time object.


(decode-time (date-to-time "Tue, 27-Sep-83 12:35:59 EST"))
==> (59 35 13 27 9 1983 2 t -14400)

Get the seconds from the unix epoch.


(let ((time (date-to-time "13 Feb 2009 23:31:30 UTC")))
(float-time time))
==> 1234585890.0

Find the date for seconds from the unix epoch.


(format-time-string "%Y-%m-%d %T UTC" (seconds-to-time 1234585890))
==> "2009-02-13 23:31:30 UTC"

Find the date 30 seconds in the future.


(format-time-string "%Y-%m-%d %T UTC" (time-add (current-time)
(seconds-to-time 30)))
==> "2012-02-13 10:07:11 UTC"

Formatting elapsed time in years, days, hours, minutes and seconds.


(format-seconds "%Y %D %h:%m:%s" (1- (* 367 24 3600)))
==> "1 year 1 day 23:59:59"

Find the days between two dates.


(let ((days1 (time-to-days (date-to-time "Tue, 27-Sep-83 12:35:59 EST")))
(days2 (time-to-days (date-to-time "2009-02-13 23:31:30 UTC"))))
(- days2 days1))
==> 9271

Getting the day in the year.


(time-to-day-in-year (current-time))
==> 44

Build a date based on the day of the year.


(format-time-string "%j"
(encode-time 0 0 0 44 1 2012))
==> "044"

Pattern matching
“Patterns” refers to RegularExpressions.
There’s a set of functions that work in strings, and a set that work in buffers.

Finding
(string-match "foo*" "Fight foo for food!")
==> 6

Using a temporary buffer instead:


(with-temp-buffer
(insert "Fight foo for food!")
(goto-char (point-min))
(re-search-forward "foo*")
(point))
==> 10

Alternative without regular expressions: ‘search-forward’.

The functions working on buffers move point to the end of the occurrence found and return it. That’s
why the result is 10 instead of 6.

Verifying
Sometimes you just want to check whether you’re at the right place:
(with-temp-buffer
(insert "Fight foo for food!")
(goto-char (point-min))
(looking-at "fight"))
==> t

Search and replace


(replace-regexp-in-string "foo*" "fu" "Fight foo for food!")
==> "Fight fu fur fud!"

Using a temporary buffer instead:


(with-temp-buffer
(insert "Fight foo for food!")
(goto-char (point-min))
(while (re-search-forward "foo*" nil t)
(replace-match "fu"))
(buffer-string))
==> "Fight fu fur fud!"

Alternative without regular expressions: ‘search-forward’.

See also StringSearchAndReplace.

Search and do something with match


This finds numbers and increments them by one. It depends on ‘decimal-number’ that was
defined above. See also IncrementNumber.
(while (re-search-forward "[0-9]" nil t)
(goto-char (match-beginning 0))
(when (and (looking-at "[-+]?[0-9]+\\.?[0-9]*")
(decimal-number (match-string 0)))
(replace-match
(number-to-string (1+ (string-to-number (match-string 0)))))
(goto-char (match-end 0))))

This loads EmacsLisp files listed one per line in a text file.
(with-current-buffer (find-file-noselect "~/load-files.txt")
(while (re-search-forward "^.*\\.el\\(\\.gz\\)?$" nil t)
(let ((filename (match-string 0)))
(when (file-exists-p filename)
(load-file filename)))))

Extracting submatches from a regex match


Like in most other regex implementations, if you use grouping parentheses in a regular expression, you
can extract the text that matched each parenthesized group. Groups are numbered from the opening
parenthesis, left to right. These are also called back references, or backrefs, or matching groups.
(save-match-data ; is usually a good idea
(and (string-match "\\`\\([^@]+\\)@\\([^@]+\\)\\'" email)
(setq user (match-string 1 email)
domain (match-string 2 email) ) ))

Usually you would use *let* instead of *setq* but this is just a simple self-contained example. See
also DynamicBindingVsLexicalBinding.

Mapping with a regex


This invokes a function at every match of a regexp:
(defun map-regex (buffer regex fn)
"Map the REGEX over the BUFFER executing FN.

FN is called with the match-data of the regex.

Returns the results of the FN as a list."


(with-current-buffer buffer
(save-excursion
(goto-char (point-min))
(let (res)
(save-match-data
(while (re-search-forward regex nil t)
(let ((f (match-data)))
(setq res
(append res
(list
(save-match-data
(funcall fn f))))))))
res))))

An example use might be:


(map-regex
(find-file-noselect "~/work/elnode-auth/build-parts.txt")
"^\\(.*.el\\(\\.gz\\)*\\)$"
(lambda (md)
(let ((filename (match-string 0)))
(when (file-exists-p filename)
(load-file filename))))))
Finding all the strings that match
If you want to list all the matching strings, including subexpressions:
(defun match-strings-all (&optional string)
"Return the list of all expressions matched in last search.

STRING is optionally what was given to `string-match'."


(let ((n-matches (1- (/ (length (match-data)) 2))))
(mapcar (lambda (i) (match-string i string))
(number-sequence 0 n-matches))))

Here’s an example:
(let ((str "time help"))
(string-match "time \\([A-Za-z]+\\)$" str)
(match-strings-all str))
==> ("time help" "help")

Another variant which does something similar, but without subexpressions:


(defun regexp-list (regex string)
"Return a list of all REGEXP matches in STRING."
;; source: http://emacs.stackexchange.com/questions/7148/get-all-regexp-
matches-in-buffer-as-a-list
(let ((pos 0) ; string marker
(matches ())) ; return list
(while (string-match regex string pos)
(push (match-string 0 string) matches)
(setq pos (match-end 0)))
(setq matches (reverse matches))
matches))

And an example which locates HTML tags in the title of a publication:


(regexp-list "<[[:alnum:][:blank:]/=\"-]*?>" "An article title concerning
CO<sub>2</sub> emissions.")
==> ("<sub>" "</sub>")

Code Comments
Move to the beginning of the current comment:
(require 'newcomment)
(comment-beginning)

Move to the text after a comment:


(comment-search-forward (line-end-position) t)
See also EndOfLineNoComments.

Sequences
Datatypes used to represent sequences of things:
_____________________________________________
| |
| Sequence |
| ______ ________________________________ |
| | | | | |
| | List | | Array | |
| | | | ________ ________ | |
| |______| | | | | | | |
| | | Vector | | String | | |
| | |________| |________| | |
| | ____________ _____________ | |
| | | | | | | |
| | | Char-table | | Bool-vector | | |
| | |____________| |_____________| | |
| |________________________________| |
|_____________________________________________|

Lists
List basics are explained at ListStructure. Lists can shrink and grow, but access to elements towards the
end of the list is slow if the list is long.
Use ‘cons’, ‘push’, or ‘add-to-list’ to prepend a new element to a list. Use ‘nth’ to
access an element of a list.
(let ((words '("fight" "foo" "for" "food!")))
(when (string= "foo" (nth 1 words))
(setq words (cons "bar" words)))
words)
==> ("bar" "fight" "foo" "for" "food!")

See ListModification for more ways of changing a list.


Iteration:
(let ((result ()))
(dolist (word '("fight" "foo" "for" "food!"))
(when (string-match "o" word) (push word result)))
(nreverse result))
==> ("foo" "for" "food!")

Note how ‘push’ adds an element to the front of the list, so that usually the list has to be reversed
after the loop. ‘nreverse’ is particularly efficient because it does this destructively. See
DestructiveOperations for more about this.
Copying:
Use ‘copy-sequence’ to make a shallow copy of a list without changing the original.
(let* ((orig '((1 2) (3 4)))
(copy (copy-sequence orig)))
(setcdr copy '((5 6)))
(list orig copy))
==> (((1 2) (3 4)) ((1 2) (5 6)))

The elements in the copy remain in the original. More importantly, they are in fact the same elements
(i.e., ‘eq’), not copies. The list is copied, but its elements are shared with the original list.
(let* ((orig '((1 2) (3 4)))
(copy (copy-sequence orig)))
(setcdr (cadr copy) '(0))
(list orig copy))
==> (((1 2) (3 0)) ((1 2) (3 0)))

‘copy-tree’ is the recursive version of ‘copy-sequence’.


(let* ((orig '((1 2) (3 4)))
(copy (copy-tree orig)))
(setcdr (cadr copy) '(0))
(list orig copy))
==> (((1 2) (3 4)) ((1 2) (3 0)))

Filtering:
A ‘filter’ macro has been added to the Emacs development tree. It does what you expect: filters a
list, returning a copy that keeps elements that satisfy a predicate and omitting elements that do not
satisfy it.
If your Emacs does not yet have this built in, you can use ‘dolist’ or ‘mapcar’ to iterate over a
list with a conditional, and then use ‘delq’ to remove the ‘nil’ values.
(defun my-filter (condp lst)
(delq nil
(mapcar (lambda (x) (and (funcall condp x) x)) lst)))

Therefore,
(my-filter 'identity my-list)

is equivalent to
(delq nil my-list)

For example:
(let ((num-list '(1 'a 2 "nil" 3 nil 4)))
(my-filter 'numberp num-list))
==> (1 2 3 4)

Package ‘cl-seq’ has functions ‘remove-if’ and ‘remove-if-not’. The latter can be used
instead of ‘my-filter’.
(let ((num-list '(1 'a 2 "nil" 3 nil 4)))
(remove-if-not 'numberp num-list))
==> (1 2 3 4)

(let ((num-list '(1 'a 2 "nil" 3 nil 4)))


(remove-if 'numberp num-list))
==> ((quote a) "nil" nil)

Here is a version of quicksort:


(defun quicksort (lst)
"Implement the quicksort algorithm."
(if (null lst) nil
(let* ((spl (car lst))
(rst (cdr lst))
(smalp (lambda (x)
(< x spl))))
(append (quicksort (remove-if-not smalp rst))
(list spl)
(quicksort (remove-if smalp rst))))))

(quicksort '(5 7 1 3 -9 8 7 -4 0))


==> (-9 -4 0 1 3 5 7 7 8)

The following function was written by tali713 in response to hypnocat’s question regarding a filter
function in #emacs:
(defun keep-when (pred seq)
(let ((del (make-symbol "del")))
(remove del (mapcar (lambda (el)
(if (funcall pred el) el del)) seq))))

Use:
(keep-when 'atom '(1 2 3 (4 5) 6 nil t foo))
==> (1 2 3 6 nil t foo)

Updated 31/05/2013.
Tranposing:
Create a list from multiple lists:
((lambda (&rest args)
(mapcar (lambda (n)
(delq nil (mapcar (lambda (arg) (nth n arg)) args)))
(number-sequence 0 (1- (apply 'max (mapcar 'length args))))))
'(1 2 3) '(a b c) '(A B C))
==> ((1 a A) (2 b B) (3 c C))

A more concise version is possible with the the higher-arity version of ‘mapcar’ available from
library ‘cl’.
((lambda (&rest args)
(apply (function mapcar*) (function list) args))
'(1 2 3) '(a b c) '(A B C))
==> ((1 a A) (2 b B) (3 c C))

Searching:
You can check for presence of a value in a list using ‘member’ or ‘memq’.
(let ((words '("fight" "foo" "for" "food!")))
(car (member "for" words)))
==> "for"

(let ((re "\\wo\\b")


(words '("fight" "foo" "for" "food!")))
(consp (memq t
(mapcar (lambda (s) (numberp (string-match re s))) words))))
==> t

In the latter, a more efficient algorithm would use a loop (a non-local exit).

Association lists
The ElispManual has examples of finding and deleting values in an association list, or alist. Here are
cases when the car values are strings.
(assoc "2" '(("2" . 2) ("1" . 1) ("2") ("3" . 3)))
==> ("2" . 2)

(mapcar (lambda (c) (cons c (string c))) (number-sequence 56 65))


==> ((56 . "8") (57 . "9") (58 . ":") (59 . ";") (60 . "<")
(61 . "=") (62 . ">") (63 . "?") (64 . "@") (65 . "A"))
(assq 64
(mapcar (lambda (c) (cons c (string c))) (number-sequence 56 65)))
==> (64 . "@")
(assq 55
(mapcar (lambda (c) (cons c (string c))) (number-sequence 56 65)))
==> nil

Deleting:
(let ((alist '(("a" . 1) ("b" . 2))))
(delq (assoc "a" alist) alist))
==> (("b" . 2))

Matches with a test function other than ‘equal’:


(let ((alist '(("ab" . 1) ("bc" . 2) ("cd" . 3))))
(assoc-default "c" alist (lambda (x y) (string-match y x))))
==> 2

The alist functions are useful for finding the first instance of a value in any list, not just association
lists, and even when there are duplicates.
The following uses ‘mapcar’ to associate the ‘major-mode’ to each buffer returned by
‘buffer-list’, then ‘assq’ to find the first buffer where the major mode is ‘fundamental-
mode’.
(assq 'fundamental-mode
(mapcar
(lambda (b)
(cons (buffer-local-value 'major-mode b) b))
(buffer-list)))
==> (fundamental-mode . #<buffer *Messages*>)

You can also find values in regular lists, by converting them to association lists with a null cdr.
Here’s an association list of random numbers with no associated value.
'((8 . nil) (3 . nil) (1 . nil) (7 . nil) (3 . nil) (6 . nil) (9 . nil))
==> ((8) (3) (1) (7) (3) (6) (9))

This is really just making a list for each number – a “list of lists” – which can be done with ‘mapcar’
and ‘list’.
(mapcar 'list '(8 3 1 7 3 6 9))
==> ((8) (3) (1) (7) (3) (6) (9))
(assq 3 (mapcar 'list '(8 3 1 7 3 6 9)))
==> (3)

To group elements by a function:


(defun group-by-eq (f lst)
"Build `assq`-list based on result of F on Xs in LST."
(let ((alist))
(dolist (x lst)
(let* ((key (funcall f x)) ;; This should give an `eq`-able value.
(vals (assq key alist))) ;; Look for it in the association list.
(if (null vals)
(setq alist (cons (list key x) alist))
(setcdr vals (cons x (cdr vals))))))
(nreverse alist)))

To group cons-cells by their car:


(group-by-eq 'car '((a 0) (b 0) (b 1)))
==> ((a (a 0)) (b (b 1) (b 0)))

To group a list of integers by their negativity:


(group-by-eq (lambda (x) (< x 0)) '(0 -1 2 -3 4 -5))
==> ((t -5 -3 -1) (nil 4 2 0))

Vectors
Vectors are fixed in size, and their elements can be accessed in constant time (neither of which is the
case for lists).
(let ((words ["fight" "foo" "for" "food!"]))
(when (string= "foo" (aref words 1))
(aset words 1 "bar"))
words)
==> ["fight" "bar" "for" "food!"]

Convert vector to list


All vectors are sequences and the map functions work on sequences, so:
(mapcar 'identity [1 2 3 4])
==> (1 2 3 4)

Here is another Lisp idiom for the same thing:


(append [1 2 3 4] ())
==> (1 2 3 4)

Hash tables
Hash tables map keys to values. They are similar to alists, but they are typically more efficient for a
large number of keys.
See HashMap.

Storing and retrieving keys and values


By default, hash tables use ‘eql’ to compare keys. This is not appropriate for strings: (eql
"alex" "alex") ⇒ nil. Use ‘equal’ in such cases:
(let ((nick-table (make-hash-table :test 'equal)))
(puthash "kensanata" "Alex Schroeder" nick-table)
(gethash "kensanata" nick-table))
==> "Alex Schroeder"

Iterate:
(let ((nick-table (make-hash-table :test 'equal))
nicks)
(puthash "kensanata" "Alex Schroeder" nick-table)
(puthash "e1f" "Luis Fernandes" nick-table)
(puthash "pjb" "Pascal J. Bourguignon" nick-table)
(maphash (lambda (nick real-name)
(setq nicks (cons nick nicks)))
nick-table)
nicks)
==> ("pjb" "e1f" "kensanata")

Sorting keys
Use ‘maphash’ to build up a list of keys, sort it, and then loop through the list:
(let ((nick-table (make-hash-table :test 'equal))
nicks)
(puthash "kensanata" "Alex Schroeder" nick-table)
(puthash "e1f" "Luis Fernandes" nick-table)
(puthash "pjb" "Pascal J. Bourguignon" nick-table)
(maphash (lambda (nick real-name)
(setq nicks (cons nick nicks)))
nick-table)
(mapcar (lambda (nick)
(concat nick " => " (gethash nick nick-table)))
(sort nicks 'string<)))
==> ("e1f => Luis Fernandes"
"kensanata => Alex Schroeder"
"pjb => Pascal J. Bourguignon")

Files
Read
A file can be inserted at point with ‘insert-file-contents’ or ‘insert-file-
contents-literally’. To get a file as a string,
(defun file-string (file)
"Read the contents of a file and return as a string."
(with-temp-buffer
(insert-file-contents file)
(buffer-string)))

On the chance that a buffer may already be actively visiting the file, consider using ‘find-file-
noselect’
(defun file-string (file)
"Read the contents of a file and return as a string."
(with-current-buffer (find-file-noselect file)
(buffer-string)))

Filter
Processing a file is usually done with a temporary buffer:
(defun process-file (file)
"Read the contents of a file into a temp buffer and then do
something there."
(when (file-readable-p file)
(with-temp-buffer
(insert-file-contents file)
(goto-char (point-min))
(while (not (eobp))
;; do something here with buffer content
(forward-line)))))
Write
To write something to a file you can create a temporary buffer, insert the things to write there and write
the buffer contents to a file. The following example read a string and a filename (with completion, but
doesn’t need to exist, see InteractiveCodeChar F) and write the string to that file.
(defun write-string-to-file (string file)
(interactive "sEnter the string: \nFFile to save to: ")
(with-temp-buffer
(insert string)
(when (file-writable-p file)
(write-region (point-min)
(point-max)
file))))

Another way to do this is via with-temp-file:


(defun write-string-to-file (string file)
(interactive "sEnter the string: \nFFile to save to: ")
(with-temp-file file
(insert string)))

Input and output (I/O)


This is a nice and simple way to edit a file with Emacs Lisp, especially when there’s a chance the file
might be already be visited in Emacs and its ok to edit the existing buffer.
(with-current-buffer (find-file-noselect "~/logfile")
(goto-char (point-max))
(insert (format "Hash of last line: %s"
(md5
(save-excursion
(forward-line -1)
(buffer-substring-no-properties (point)
(line-end-position))))))
(newline)
(with-temp-message "Writing file..."
(save-buffer))
(message "Writing file...done"))

Searching within a File


If you don’t have grep, then you may need to write some Lisp which can find a match in a file.
;; Visit file unless its already open.
(with-current-buffer (find-file-noselect "~/.emacs")
(save-excursion ;; Don't change location of point.
(goto-char (point-min)) ;; From the beginning...
(if (re-search-forward ".*load-path.*" nil t 1)
(match-string-no-properties 0)
(error "Search failed"))))
==> "(add-to-list 'load-path \"/usr/share/emacs/site-lisp/\")"
Locking
(unless (file-locked-p (buffer-file-name))
(lock-buffer))

Stat
An interface to the kernel’s stat(2) is provided by the function file-attributes.
(let* ((attrs (file-attributes (buffer-file-name)))
(atime (nth 4 attrs))
(mtime (nth 5 attrs))
(ctime (nth 6 attrs)))
(concat "File last accessed on "
(format-time-string "%Y-%m-%d %T" atime) "\n"
"File last modified on "
(format-time-string "%Y-%m-%d %T" mtime) "\n"
"File last changed on "
(format-time-string "%Y-%m-%d %T" ctime) "\n"))

Deleting
(if (file-exists-p filename)
(delete-file filename))

Copy, move and rename


(copy-file file new-name)

(rename-file file new-dir)

(rename-file file new-name)

Copy the buffer filename for yanking


(defun copy-buffer-file-truename (&optional as-host-os-path)
"Copy the buffer-file-truename to the kill ring.
Also, display it in the `*Messages*' buffer.

If AS-HOST-OS-PATH is nil, use the Emacs representation,


otherwise use 'something suitable for the OS'."
(interactive "P")
(if (not buffer-file-truename)
(error "%s" "This buffer has no filename")
(set 'path (expand-file-name buffer-file-truename))
(kill-new (if as-host-os-path (convert-standard-filename path) path))
(message "%s" (current-kill 0 t))))
Directories
Listing
All files in a directory sorted by name:
(directory-files "~/")
==> ("." ".." ".bash_history" ".bashrc" ".emacs" ".emacs.d" "diary" "local"
"public_html")

File names matching a regular expression and in no particular order.


(directory-files "~/" (not 'absolute) "\\`\\." 'nosort)
==> (".emacs.d" ".emacs" ".bash_history" ".bashrc" ".." ".")

File names matching a wildcard expression sorted by name.


(let ((default-directory "~/"))
(file-expand-wildcards "?emacs*"))
==> (".emacs" ".emacs.d")

All files sorted by modification time:


(let ((default-directory "~/"))
(sort
(directory-files default-directory (not 'absolute) nil 'nosort)
(lambda (a b)
(time-less-p (nth 5 (file-attributes a))
(nth 5 (file-attributes b))))))
==> (".bashrc" "diary" "public_html" "local" ".bash_history" ".." ".emacs"
".emacs.d" ".")

Recursion
Here’s an example of using ‘directory-files’ to find all subdirectories in a subdirectory.

Could potentially surpass ‘max-lisp-eval-depth’ if the filesystem has a suffienctly complex


number of subdirectories.
(defun directory-dirs (dir)
"Find all directories in DIR."
(unless (file-directory-p dir)
(error "Not a directory `%s'" dir))
(let ((dir (directory-file-name dir))
(dirs '())
(files (directory-files dir nil nil t)))
(dolist (file files)
(unless (member file '("." ".."))
(let ((file (concat (file-name-as-directory dir) file)))
(when (file-directory-p file)
(setq dirs (append (cons file
(directory-dirs file))
dirs))))))
dirs))

Giving ‘directory-dirs’ an absolute file name:


(directory-dirs "/emacs/lisp")
==> ("/usr/share/emacs/23.2/lisp/calc" "/usr/share/emacs/23.2/lisp/calendar"
"/usr/share/emacs/23.2/lisp/cedet"
"/usr/share/emacs/23.2/lisp/cedet/ede" ...)

Setting the ‘default-directory’ to a directory allows ‘directory-dirs’ to return relative


file names for subdirectories.
(let ((default-directory "/usr/share/emacs/23.2/lisp"))
(directory-dirs "."))
==> ("./calc" "./calendar" "./cedet" "./cedet/ede" ...)

Traversing
A file-tree-walk function has been added to the Emacs development tree. Until it lands in your version,
you can use this:
(defun walk-path (dir action)
"walk DIR executing ACTION with (dir file)"
(cond ((file-directory-p dir)
(or (char-equal ?/ (aref dir(1- (length dir))))
(setq dir (file-name-as-directory dir)))
(let ((lst (directory-files dir nil nil t))
fullname file)
(while lst
(setq file (car lst))
(setq lst (cdr lst))
(cond ((member file '("." "..")))
(t
(and (funcall action dir file)
(setq fullname (concat dir file))
(file-directory-p fullname)
(walk-path fullname action)))))))
(t
(funcall action
(file-name-directory dir)
(file-name-nondirectory dir)))))
(defun walk-path-visitor (dir file)
"Called by walk-path for each file found"
(message (concat dir file)))

(walk-path "~/" 'walk-path-visitor)

Path splitting
Splitting the path can be done with ‘split-string’ and with the slash. Previously, Emacs would
determine the character separating directory names with ‘directory-sep-char’. However, the
variable is obselete with Emacs 21.1.
(split-string default-directory "/")
==> ("" "usr" "share" "emacs" "22.2" "lisp" "")

For splitting a path variable, Emacs already has the ‘parse-colon-path’ function.
(parse-colon-path (getenv "PATH"))
==> ("/usr/lib/qt-3.3/bin/" "/usr/kerberos/bin/" "/usr/local/bin/" "/usr/bin/" "/
bin/" "/usr/local/sbin/" "/usr/sbin/" "/sbin/")

Processes
Running a program
Run a command without caring about its output.
(async-shell-command "emacs")

Run a command and put its output in the current buffer.


(shell-command "seq 8 12 | sort" t)
10
11
12
8
9

Run a command and put its output in a new buffer.


(shell-command "seq 8 12 | sort"
(get-buffer-create "*Standard output*"))

Run a command return its output as a string.


(shell-command-to-string "seq 8 12 | sort")

Run a command return and insert its output at point in the current buffer.
(insert (shell-command-to-string "date"))
Handling signals

Sockets
Tcp client

Tcp server
Perhaps EmacsEchoServer and EmacsDaytimeServer can be useful here. Also Edit with Emacs' edit-
server.el which is a more complete server implementation.

Keys
Call function bound to key
(funcall (key-binding (kbd "M-TAB")))

or
(call-interactively (key-binding (kbd "M-TAB")))

Documenting key binding to lambda


See DocumentingKeyBindingToLambda

Test code
Sometimes you might want to insert some demonstration code in a module. The code should not be run
when the module is loaded via ‘require’ or ‘load’ but when you ‘eval-current-
buffer’. All you need to do add is add a test condition of ‘eval-buffer-list’:
(dont-compile
(when (eq (car eval-buffer-list) (current-buffer))
...))

This work is licensed to you under version 2 of the GNU General Public License. Alternatively, you
may choose to receive this work under any other license that grants the right to use, copy, modify, and/
or distribute the work, as long as that license imposes the restriction that derivative works have to grant
the same rights and impose the same restriction. For example, you may choose to receive this work
under the GNU Free Documentation License, the CreativeCommons ShareAlike License, the XEmacs
manual license, or similar licenses.
Please note our Privacy Statement.

Potrebbero piacerti anche