An Introduction to Emacs Lisp: Working with Files and Their Attributes

A hands-on introduction to the Emacs Lisp scripting language and working with files in Emacs

Image for post
Image for post

Introduction

Source Code

$ curl -L https://raw.githubusercontent.com/danebulat/elisp-samples/master/file-attributes/file-attributes.el > file-attributes.el
$ git clone https://github.com/danebulat/elisp-samples

Emacs Refresher

Evaluating Emacs Lisp Code

(setq variable-name initial-value)
(setq greeting "Hello, world!")
(message "The value of greeting variable: %s" greeting)
(defun function-name (arg1, arg2)
"Document string explaining ARG1 and ARG2."
;; body
)
(defun output-message (string-to-output)
"A simple function that outputs STRING-TO-OUTPUT via the
`message' function."
(message "Output message: %s" string-to-output))
(output-message "Hello, world!")

Working With File Attributes

(file-attributes FILENAME &optional ID-FORMAT)
Items returned by the file-attributes function.
(file-attributes "~/.bashrc")
-| (nil 1 1000 1000
(24588 61261 769551 700000)
(24574 56146 828467 818000)
(24574 56146 828467 818000)
1693 "-rw-r--r--" t 14686928 66310)
;; Variable that points to the file attributes list
(setq attributes (file-attributes "~/.bashrc"))
;; Output first item
(car attributes)
;; Output fifth item (last access time)
(car (nthcdr 4 attributes))
;; Another way to output the fifth item
(car (cdr (cdr (cdr (cdr attributes)))))
;; Output tenth item (file modes)
(car (nthcdr 9 attributes))
Built-in functions that retrieve particular file attributes.
;; Create a variable that points to the file attributes list
(setq attributes (file-attributes "~/.bashrc"))
;; Pass variable to file attribute functions
(file-attribute-user-id attributes)
(file-attribute-size attributes)
(file-attribute-device-number (file-attributes "~/.bashrc"))
(file-attribute-inode-number (file-attributes "~/.bashrc"))
(message "Last access time: %s"
(file-attribute-access-time
(file-attributes "~/.bashrc")))
(message "Last modification time: %s"
(file-attribute-modification-time
(file-attributes "~/.bashrc")))

Developing Functions to Handle File Attributes

Appending a Pair of Strings to a List

(add-line (description attribute list))
(add-line "File modes" 
(file-attribute-modes attributes) output-list)
(add-line "File size (in bytes)"
(file-attribute-size attributes) output-list)
The add-line function.
(when (equal attribute nil)
(setq attribute "nil"))
(unless (stringp attribute)
(setq attribute (number-to-string attribute)))
(setq list (cons description list))
(setq list (cons attribute list)))
;; Temporary code for testing the add-line function
(setq attributes (file-attributes "~/.bashrc"))
(setq output-list ())
(setq output-list (add-line "File modes"
(file-attribute-modes attributes) output-list))
(setq output-list (add-line "File size (in bytes)"
(file-attribute-size attributes) output-list))
(message "%s" output-list)

Constructing a Formatted List

(defun formatted-file-attributes (filename))
The formatted-file-attributes function.
(interactive "fFile name: ")
(let ((attributes (file-attributes filename))
(out-list ()))
(setq out-list (add-line "File type"
(file-attribute-type attributes) out-list))
(setq out-list (add-line "Links"
(file-attribute-link-number attributes) out-list))
;; And so on
(setq out-list 
(add-line "Last Access Time"
(format-time-string "%D"
(file-attribute-access-time attributes))
out-list))
(setq out-list (nreverse out-list))))
(formatted-file-attributes "~/.bashrc")

Outputting to the Messages Buffer

(defun file-attributes-to-messages (filename))
The file-attributes-to-messages function.
(let ((out-list (format-file-attributes filename)))
(message "%20s: %s\n\n" "Filename" filename)
(while out-list
(message "%20s %s\n"
(car out-list) (car (nthcdr 1 out-list)))
(setq out-list (cdr (cdr out-list))))))
(file-attributes-to-messages "~/.bashrc")

Conclusion

MSc. Programmer and fan of open source software.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store