Learning Elisp 03 Reading and Writing Buffer in Emacs
Basic API for Emacs Buffers
Buffers may be visible or not.
Manipulating Buffer
Current buffer
1(current-buffer)
Get buffer by name or create one (get-buffer-create
)
1
2(get-buffer "*scratch*")
Create a buffer if it doesn’t already exist:
1
2(get-buffer-create "Hello World")
Changing the current buffer (set-buffer
)
1(progn
2 (set-buffer (get-buffer "*scratch*"))
3 (current-buffer))
4
5;;equivalently
6(progn
7 (set-buffer "*scratch*")
8 (current-buffer))
progn
is an expression that allows you to run multiple expression inside of the body.
Changing the current buffer safely (save-current-buffer
)
The set-buffer
command may affect the code run afterwards: (the
command that’s supposed to run in other buffer now run in the
scratch buffer because that’s what set by the set-buffer
function.
Solution: using save-current-buffer
1(progn
2 (save-current-buffer
3 (set-buffer "*scratch*")
4 (message "Current buffer: %s" (current-buffer)))
5 (current-buffer))
Alternatively,
1(progn
2 (with-current-buffer "*scratch*"
3 (message "Current buffer: %s" (current-buffer)))
4 (current-buffer))
Manipulating Files
File of the current buffer (buffer-file-name
)
use buffer-file-name
to find/obatin the file name and the full path of the
file the buffer represented:
1
2(buffer-file-name)
Find the existing buffer that is represented by the file path (provide
as much information as possible about the file path) using
get-file-buffer
.
- If the file is not currently open in the buffer the function will
return
nil
1
2(get-file-buffer "~/Notes/Emacs/reading-and-writing-buffers.org")
Load files into a buffer (find-file-noselect
)
1(find-file-noselect "function.org")
- If running the command more than once the file will be loaded into the same buffer and sometimes it’s not what we want (the buffer may not refect the most recent change of the file)
- send
t
to the second argument to prevent a prompt when the file is modified and differ from the buffer
1(find-file-noselect "function.org" t)
Manipulating file paths (prefix file-name
)
In Emacs, file paths are decomposed into two parts: 1. directory part; 2. file name and extension.
Function prefix : file-name
.
-directory
- get the directory part of a file path-nondirectory
- get the filename of the file path-extension
- get the extension of the file without the leading period-sans-extension
- get the path without extension-base
- get the file name without path or etension-as-directory
- turn the file name into a directory name
An interesting example
1(file-name-as-directory
2 (file-name-sans-extension (buffer-file-name))) ;; turn the current file name into another path
Resolving file paths (file-name-absolute-p
etc)
file-name-absolute-p
file-relative-name
- give the path of a file relative to another pathexpand-file-name
- return the absolute path for a file under a specified directory
1
2(file-name-absolute-p (buffer-file-name)) ;;t
3
4(file-relative-name (buffer-file-name) "~/Notes")
5(file-relative-name (buffer-file-name) "~/.dotfiles")
6
7(expand-file-name "function.org")
8
9(expand-file-name "Emacs.org" "~/.dotfiles")
If resolving files that contains Environmental Variable,
expand-file-name
won’t work, use substitute-in-file-name
instead
1(substitute-in-file-name "$HOME/.emacs.d")
Check if file exists
file-exists-p
- check if the file or directory exsits;
1(file-exists-p "~/.dotfiles/.files/.emacs.d")
Other options:
file-readable-p
file-executable-p
file-writable-p
Manipulating Directories
Creating directories (make-directory
)
1
2(make-directory "~/Notes/Emacs/Test")
3
4;;create directory with path that doesn't exist
5;;add t as the second parameter
6
7(make-directory "~/Notes/Emacs/test1/test2" t)
Listing files in directories
Using directory-files
and directory-files-recursively
.
1
2(directory-files "~/.dotfiles") ;;return a list of files names with extension
3(directory-files "~/.dotfiles" t) ;;return the full path of files in the list
4(directory-files "~/.dotfiles" t ".org") ;; Get all file containing '.org'
5
6;; listing all the subfolders file
7(directory-files-recursively "~/.dotfiles" "\\.el$") ;; the last argument is a simple regexp
8(directory-files-recursively "~/.dotfiles/.files" "")
9(directory-files-recursively "~/.dotfiles" "" t) ;;return the folder as well as the files
10
11;; forth parameter is a lambda function that can ba passed onto the function to restrict the path the doc can search into (this one is very tricky!)
12(directory-files-recursively "~/.dotfiles" "" t
13 (lambda (dir)
14 (progn
15 (message "The dir is: %s" dir)
16 (string-equal dir "~/.dotfiles/.files"))))
17
18;; The fifth parameter is used to specify whether the path should follow symbolic link
Copying, moving and deleting files and dir
Copy-file
: copy the contents of one file to anotherCopy-directory
: copy the contents including the subdirectories into another dir
Caveat: elisp treat /folder
and /folder/
differently, if you want to
present the symbol as a folder, be sure to include /
at the end of it.
1(copy-file "~/.emacs.d/init.el" "~/exp/") ;; if using "~/exp" will throw err
2;; (directory-files "~/exp")
3;;to ignore that the file already exists
4(copy-file "~/.emacs.d/init.el" "~/exp/" t)
5
6;; copy directory
7
8;; (directory-files-recursively "~/.emacs.d" "" t
9;; (lambda (dir)
10;; (string-equal dir "~/.emacs.d/lisp"))) ;; no directory called lisp
11
12(copy-directory "~/.emacs.d/snippets" "/tmp")
Renaming/Moving
rename-file
: rename a file or directory
1
2(copy-file "~/.emacs.d/init.el" "/tmp/")
3(rename-file "/tmp/init.el" "/tmp/init-rename.el")
Deleting
delete-file
: Delete a file. (optionally moving it to eh trash folder)delete-directory
: Delete a directory, including files if disired
1
2(delete-file "/tmp/init-rename.el")
3
4;;delete folder (optionally, including the contents)
5
6(delete-directory "~/exp") ;; return err message because the folder is not empty
7(delete-directory "~/exp" t)
Creating Symblink
make-symbolic-link
: create symbolic link, set the third arg tot
, so it won’t through error even if the symblink already exists
1
2(make-symbolic-link "~/.dotfiles/.zshrc" "~/.zshrc" t)
file-symlink-p
: check if the file is a symblink filefile-truename
: return the fule resolved path of the symblink file
1
2(file-symlink-p "~/.zshrc")
3(file-truename "~/.zshrc")