Skip to content

Instantly share code, notes, and snippets.

@algal
Last active September 6, 2022 17:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save algal/bc84a6762025aa2884badd51fdffdbd8 to your computer and use it in GitHub Desktop.
Save algal/bc84a6762025aa2884badd51fdffdbd8 to your computer and use it in GitHub Desktop.
Boilerplate to write a command line script in emacs lisp
:;exec emacs --no-init-file --no-site-lisp -script "$0" -- "$@" # -*- mode:emacs-lisp -*-
(defun main ()
(require 'cl-lib)
(let ((script-name (nth 2 command-line-args))
(args (cdr command-line-args-left)))
;; assert: ARGS now is a possibly empty list of command line args to the script
;; check for valid arguments here
(when (not args)
(princ (format "usage: %s PATH_TO_FILE" script-name))
(kill-emacs))
;; start real work here
(princ (format "Hello world. Argument list: %S\n" args))
;; ;; example of creating a file by modifying
;; (let* ((orig-filename (nth 0 args))
;; (new-filename (format "%s.fixed" orig-filename)))
;; (find-file new-filename)
;; (insert-file-contents orig-filename)
;; ;; do buffer-transforming work here
;; (let ((replaced (replace-regexp-in-region " [, α-ωά-ώ]+\n\n[, Ά-ΏΑ-Ω]+"
;; "CHAPTERHERE\n\1")))
;; (princ (format "Replaced %s instances\n" replaced)))
;; (save-buffer))
))
(main)
;; Q: Why does the initial line work?
;;
;; The file is valid elisp, because : is a no-op as a self-evaluating
;; value, and ; comments out the rest of the line.
;;
;; It's also valid sh, since : triggers interpretation, ; is sh no-op as
;; the command delimiter, and "exec" hands over process control, which
;; stops sh from reading the remaining lines.
;;
;;
;; notes on this:
;; - https://www.emacswiki.org/emacs/BatchMode
;; - https://www.emacswiki.org/emacs/EmacsScripts
;; - https://emacs.stackexchange.com/a/10132/9190
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment