Fun Things I Setup In Emacs
How Did I Find Emacs?
I deeply enjoy programming. As time went on, I got more and more interested in tooling beyond VS Code. I remember, one day, being so upset and visually disturbed at chaotic layout. Colors here, colors there, buttons here, collapsable widgets there.
It truly disturbed me.
Anyways, I learned how to insert, :wq and :q from Vim. I didn't really enjoy its editing style. I tried Helix, which actually was really enjoyable. But it felt too rigid (I respect how it has a focused goal, and this is a productive out of the box choice).
I heard about Emacs and was interested by Elisp. I tried Emacs, and at first it was awkward. But being able to craft an environment exactly to my design was both a pleasurable waste of time and immensely practical.
Fun Things I Setup
Automated Deployment Of My Blog
Compile is one of the greatest built in tools, without a doubt. Emacs is a joy when programming compiled languages, not so much with interpreted languages.
(defun deploy-writing ()
"Hugo -> Cloudflare"
(interactive)
(let ((default-directory writing-project-path))
(compile (format "cd '%s' && hugo && wrangler pages deployment create '%s/public' --project-name=totallynotdavid"
writing-project-path
writing-project-path))))I used to manually deploy my blog, which led to months where I didn't push any changes. I simply am too lazy to setup a CICD pipeline.
But now I can run one command, deploy it, and refresh my website and see the changes instantly. (thanks Cloudflare)
(global-set-key (kbd "C-c d") deploy-writing)Automated Backups Of My Writings
I pay for a file backup service. The remote filesystem is mounted to my local computer. I wrote a Rust CLI tool that would parse all my writings, categorize them by date, format it particularly, and move the files from local -> remote.
(defun push-to-drive ()
"Backup essays to remote FS"
(interactive)
(message "Backing up essays")
(compile "eorg"))I can similarily call that command with one keybinding.
(global-set-key (kbd "C-c .") 'push-to-drive)Environment Specific Org Mode Setup
I have an Org mode setup that changes between work and home computers:
defcustom is-work-computer nil
"Having fun at work?"
:type 'boolean
:group 'user)
(defcustom is-environment-configured nil
"Whether org-mode was configured"
:type 'boolean
:group 'user)
(defvar notes-base-dir "~/org/")
(defvar work-notes-file (concat notes-base-dir "work.org"))
(defvar home-notes-file (concat notes-base-dir "personal.org"))
(defun make-notes-file-if-not-exists (dir file)
"create notes directory and file if needed"
;; make directory if not exists
(unless (file-exists-p dir)
(make-directory dir))
;; make file if not exists
(unless (file-exists-p file)
(with-temp-buffer
(write-file file))))
;; configure work notes environment
(defun configure-work-notes ()
"configure org mode for work"
(make-notes-file-if-not-exists "~/org/" work-notes-file)
(setq org-default-notes-file work-notes-file)
(org-agenda-files (list work-notes-file)))
(defun configure-personal-notes ()
"configure org mode for personal use"
(make-notes-file-if-not-exists "~/org/" home-notes-file)
(setq org-default-notes-file home-notes-file)
(setq org-agenda-files (list home-notes-file)))
(defun configure-environment ()
"Configure org env on first run"
(when (eq is-environment-configured nil)
(let ((is-work (y-or-n-p "Setting up emacs at work? :D")))
(customize-set-variable 'is-work-computer is-work)
(if is-work
(configure-work-notes)
(configure-personal-notes))
(customize-set-variable 'is-environment-configured t)
(customize-save-customized)
(setq org-log-done 'time))))
(if is-work-computer
(progn
(setq
org-agenda-files (list work-notes-file)
org-default-notes-file work-notes-file))
(progn
(setq
org-agenda-files (list home-notes-file)
org-default-notes-file home-notes-file)))Small joys as well…
;; enable <s TAB <q TAB templates
(require 'org-tempo)
;; lol maybe dumb but change - in lists to this dapper guy: •
(font-lock-add-keywords
'org-mode
'(("^ *\\([-]\\) " (0 (prog1 ()
(compose-region (match-beginning 1) (match-end 1) "•"))))))Just The Fact I Can Customize Everything
I don't really have anything too complex or cool other than that. Mainly just a bunch of small changes to make my Emacs config truly fit me.
It is so crazy cool I can write elisp, run M-x eval-region and see small changes appear:
;; Disable alarm
(setq ring-bell-function 'ignore)
;; Startup message
(setq inhibit-startup-message t)
;; Speed up LSP/Eglot
(setq read-process-output-max (* 1024 1024)) ; 1MB read chunks
;; Delete selected region after typing
(delete-selection-mode t)
;; Performance
(setq gc-cons-threshold 100000000)
(setq large-file-warning-threshold 100000000)
;; Start maximized
(add-to-list 'default-frame-alist '(fullscreen . maximized))
;; yes-or-no → y-or-n
(fset 'yes-or-no-p 'y-or-n-p)
;; Disable annoying auto indent
(electric-indent-mode 0)
;; Brackets come in pairs
(electric-pair-mode t)WAIT: Last Cool Thing
I configured Emacs to always show a racoon on startup. I previewed this before publishing, and so sorry for breaking the page (not really).
(setq coon-startup-ascii
" Time to do cool things!
⣿⣿⣿⣿⣿⣿⣿⠿⠿⠻⠟⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡏⣸⢿⣿⣦⣄⢀⠙⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⢱⡏⠘⣿⣿⣿⣾⣷⣤⡀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⢙⣉⣠⣬⣥⣄⢻⣿
⣿⣿⣿⣿⣿⣿⠘⣿⠎⠿⠏⠘⣿⡿⣿⠧⠀⠀⠙⠉⠻⠟⢿⣿⣿⠿⠿⠛⠋⠻⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⣀⣰⣾⣿⠿⠟⠉⠀⢉⠀⣿
⣿⣿⣿⣿⣿⣿⠆⠹⣧⠀⠀⠀⠸⡇⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠙⢿⠿⠛⠟⠛⢁⣴⣿⡿⠛⠉⠀⠀⠀⠀⠀⠀⠀⢿
⣿⣿⣿⣿⣿⣿⣧⡀⢻⡃⠀⠀⠀⠀⠀⢠⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠊⠁⢁⣦⠴⠖⠂⠀⠀⠀⠀⡴⢃⣾
⣿⣿⣿⣿⣿⣿⣿⣷⡄⠻⣇⡀⠀⠀⣀⣈⣿⣷⣿⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠀⠀⠀⠀⠀⠀⣸⢃⣾⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡁⠐⢿⣿⡃⢀⣿⣿⣿⡃⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⢀⠀⠀⠀⣀⠀⠐⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⢃⣾⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⢰⣟⠙⣾⣿⣿⣿⣿⣿⣠⣤⣤⠀⠀⠀⠀⠀⣀⣾⣿⣾⡀⣦⣾⣿⣤⣆⠀⠰⠁⠀⠀⠀⠀⠀⠀⠀⠀⣀⣼⠆⣾⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⠧⠘⣿⣦⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⢀⢀⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡆⠀⣀⡀⠀⠀⠀⠀⠀⣴⡿⢛⣤⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⢐⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣾⣿⡇⠀⠀⠀⣤⣶⣿⠏⣈⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⣸⣿⣿⣿⣿⣿⡿⠀⢸⣿⣿⡄⠀⠀⣾⣿⣿⡟⠁⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⣠⡀⠀⠻⢿⡇⠀⢿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⣿⣿⣿⡏⠀⠀⢤⠀⠀⢻⡟⢅⣀⢲⣾⡿⠛⠀⠀⠀⣀⠈⠑⠶⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⣿⣿⣷⠘⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡁⣶⣼⣿⠋⠀⠠⣄⠀⠀⠀⢸⡇⠀⠉⣿⡿⠁⠀⠀⠠⣀⠈⠁⠀⠀⠀⠀⠙⠛⠛⢛⣿⣿⣿⣿⣿⣾⣿⣿⣿⠃⣨⣿⣿⣿⣿
⣿⣿⣯⡻⢿⣿⣿⣿⡧⢿⣿⡉⠁⠀⠀⠀⠀⢀⣴⣾⣷⣄⣶⣿⣥⣄⠀⠀⠀⠉⠁⠀⠀⠀⠀⠀⠀⠈⠓⠛⠉⠙⢿⠁⠉⠸⣿⣿⣷⡶⠈⣿⣿⣿⣿
⣿⣿⣿⣿⣷⣬⣉⡙⢂⣻⠷⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢬⣦⠀⢠⣿⣿⣿⣷⣤⠈⠉⢻⣿
⣿⣿⣿⣿⣿⣿⣿⡿⠓⣹⡟⠲⠤⣄⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠶⠿⢿⣿⣿⣷⣤⡀⠙⢿
⣯⣭⣭⣉⣉⣉⡙⠓⠠⠚⠿⢶⣤⣄⣉⡾⠛⠁⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠠⢤⣀⣒⣒⣒⣒⣒⣀⣀⣀⡀⠀⠠⣼⣿⣿⣿⣆⠠⣬
⣿⠿⠟⣛⣛⡛⠛⠁⠛⢻⠶⠶⠦⠬⢽⠀⠀⠒⠆⠀⠀⠀⠀⢏⠽⠿⡿⣿⣄⠀⣤⣄⣠⣞⠉⠁⠀⠀⠀⠀⠀⠀⠀⢩⣭⣭⣭⣤⣈⡛⢿⡏⠋⠀⢹
⣿⣿⣿⡿⠟⢋⣁⣠⣄⠠⢶⣶⣶⣶⡾⡀⠀⠀⠀⠀⠀⠀⢀⠎⠀⠒⢳⣛⣿⣿⣯⠉⠳⢄⠉⠒⢄⡀⠀⠀⠀⠀⠀⠐⠚⠛⠙⣿⣟⠋⠉⠉⠀⢠⡀
⡿⣫⣵⣶⣿⣿⣿⣿⡇⠐⠛⣿⣿⣟⠃⠑⠠⠀⠀⠀⠄⠒⠁⠀⠀⠈⠉⠙⣉⠥⠁⠀⠀⠈⠣⠀⠀⠉⠢⡀⠀⠀⠀⠀⠈⠙⠻⠏⢻⣷⡀⠀⢀⠸⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣷⡞⡸⣿⣿⠟⠀⠀⠀⠐⠠⠤⠤⠤⠤⠤⠖⠒⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠄⠀⠘⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⣰⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠲⠀⠀⠀⠀⢻⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠁⢾⡷⠁⠀⢀⣤⠤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣷⣦⣷⣾⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤⢀⣤⣶⠂⠀⠈⠁⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣈⣳⣤⣶⣿⣾⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣆⣴⣿⡄⠀⠀⠀⠀⣀⡀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⣀⣤⣴⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣾⣿⣿⣿⣿⣿⣷⣶⣶⣿⣿⣷⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿")
;; focus startup screen
(setq initial-scratch-message coon-startup-ascii)
(add-hook 'after-init-hook 'move-cursor-to-top-scratch-buffer)