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)