dot-emacs

My emacs dotfiles/config
git clone git://git.ethandl.dev/dot-emacs
Log | Files | Refs

commit c96358c02c46cba428de2502235e36ae3c09eb91
parent 8fc92b518721a177c47c8f6e52dc99e4b2f211b4
Author: Ethan Long <ethandavidlong@gmail.com>
Date:   Sat, 20 Jun 2026 02:10:10 +1000

Implemented a rather ludicrous optimisation

I was able to get rid of the blocking (elpaca-wait) call by setting up
my own async queuing system w/ the async package.

Check it out if you're interested, but there are two queues; one has
eagrely defined functions, and the other has lazy functions that are
evaluated only just before execution by `async`. Really this solution is
a very overkill way of being able to use `async-inject-variables`
without the `async` package being in-scope.

This could be drastically simplified by just using a list of tuples,
with the fn being on one branch of the tuple and the inject-vars rules
being on the other, but that would be too easy... And simple...

Damn it.

Diffstat:
Mconfig.org | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 69 insertions(+), 15 deletions(-)

diff --git a/config.org b/config.org @@ -254,7 +254,7 @@ To define our desired fonts, we create functions as we did before in [[Code font Use HEIGHT to specify the font height in px, VAR as the variable-pitch font family, and MONO as the monospace font family. If HEIGHT is nil, - uses a height of 155. If VAR or MONO are nil, selects the first + uses a height of 140. If VAR or MONO are nil, selects the first available font for each from a predefined list." (setq ethandl/org-mono-font-name (or mono @@ -274,7 +274,7 @@ To define our desired fonts, we create functions as we did before in [[Code font "Times New Roman" "DejaVu Serif")))) (setq ethandl/org-font-ht - (or height 155))) + (or height 140))) #+end_src Next, we define a way to easily apply these fonts. @@ -305,19 +305,20 @@ This is not as simple as it should be, because ~variable-pitch-mode~ takes over Finally, we apply these fonts every time we enter org mode. #+begin_src emacs-lisp - (ethandl/set-org-fonts) (add-hook 'org-mode-hook #'ethandl/set-org-fonts) #+end_src ** Theme I like the Catppuccin theme, but the official one kinda stinks. As such, I use the ~batppuccin~ theme: #+begin_src emacs-lisp (elpaca batppuccin + (require 'batppuccin) (load-theme 'batppuccin-mocha t)) #+end_src Another nice theme is ~gruber-darker~ by tsoding, one can use it similarly: #+begin_src emacs-lisp :tangle no (elpaca gruber-darker-theme + (require 'gruber-darker-theme) (load-theme 'gruber-darker t)) #+end_src * Emacs behaviour @@ -350,6 +351,7 @@ For smooth mouse and faster document scrolling, I use the package ~ultra-scroll~ This works on all emacs builds to my knowledge, and is by far the best scrolling package. #+begin_src emacs-lisp (elpaca ultra-scroll + (require 'ultra-scroll) (ultra-scroll-mode 1) (add-hook 'ultra-scroll-hide-functions #'org-modern-mode)) #+end_src @@ -363,7 +365,50 @@ For debugging purposes, you can disable the tangling of this block: ** Asyncronous commands The package ~async~ allows for us to run long, blocking commands in separate Emacs processes. #+begin_src emacs-lisp - (elpaca async) + (setq ethandl/async-fn-queue nil) + (setq ethandl/lazy-async-fn-queue nil) + (setq ethandl/async-fn-evaluated nil) + + (defun ethandl/eval-async-fn-queue () + ;; Evaluate regular async fns + (push (mapcar #'async-start ethandl/async-fn-queue) + ethandl/async-fn-evaluated) + (setq ethandl/async-fn-queue nil) + + ;; Generate lazy async fns and evaluate + (let ((fns (mapcar #'funcall ethandl/lazy-async-fn-queue))) + (push (mapcar #'async-start fns) + ethandl/async-fn-evaluated)) + (setq ethandl/lazy-async-fn-queue nil)) + + (defun ethandl/async-fn-queue-add (form &optional inject-vars) + (if inject-vars + (push (lambda () + `(lambda () + ,(async-inject-variables inject-vars) + ,form)) + ethandl/lazy-async-fn-queue) + (push `(lambda () ,form) ethandl/async-fn-queue))) + + (elpaca async + (require 'async) + (ethandl/eval-async-fn-queue) + (run-with-idle-timer 30 t 'ethandl/eval-async-fn-queue)) +#+end_src +** Ahead-of-time nativecomp +After just installing this Emacs config, things can be a little stuttery. We can speed this up by telling Emacs to nativecomp everything. + +Here is a simple convenience function to compile everything in this config, including all packages installed with ~elpaca~: +#+begin_src emacs-lisp + (defun ethandl/nativecomp-aot () + (interactive) + (native-compile-async user-emacs-directory t)) +#+end_src + +We add this to the ~elpaca-after-init-hook~ so that everything is compiled after initial installation. Any subsequent compilation can occur at runtime. +#+begin_src emacs-lisp + (add-hook 'elpaca-after-init-hook + #'ethandl/nativecomp-aot) #+end_src * Org mode ** Section numbering @@ -384,6 +429,7 @@ I lied: this package is just for beauty because Org is somewhat ugly by default. Unfortunately, this package conflicts with ~visual-wrap-prefix-mode~, so we need to explicitly disable that for org mode with a hook function. #+begin_src emacs-lisp (elpaca org-modern + (require 'org-modern) (add-hook 'org-mode-hook #'org-modern-mode) (add-hook 'org-agenda-finalize-hook #'org-modern-agenda) (add-hook 'org-mode-hook (lambda () (visual-wrap-prefix-mode 0)))) @@ -420,35 +466,40 @@ If we want images generated by the output of ~org-babel~ to automatically render #+end_src This will save a ~C-c C-x C-v~ invocation every time we want to display newly generated images. * The programming environment -** Org babel env init -Throughout these subsections, I will add languages to a list of languages that Org can evaluate in code blocks. The default list includes elisp, but we will rebuild it from scratch in the following sections: +** Org babel +In addition to being a useful Markdown alternative, Org mode can also serve as a literate programming environment and (shitty) Jupyter replacement. + +The intended configuration for ~org-babel~ involves defining your list of languages to support all at once using the ~org-babel-do-load-languages~ function. +To allow for the language list (contained in ~ethandl/org-babel-langs~) to be defined dynamically (even in environment), the following function is defined: #+begin_src emacs-lisp (setq ethandl/org-babel-langs nil) (defun ethandl/org-babel-load-langs () (org-babel-do-load-languages 'org-babel-load-languages ethandl/org-babel-langs)) +#+end_src +This list is then evaluated dynamically every time an Org document is opened through the ~org-mode-hook~: +#+begin_src emacs-lisp (add-hook 'org-mode-hook #'ethandl/org-babel-load-langs) #+end_src ** The ~vterm~ terminal emulator -To make emacs a useful development environment, we need a good terminal. Instead of using a separate terminal emulator like a Unix puritan, we use the ~vterm~ package: +To make emacs a useful development environment, we need a good terminal. +In addition to using separate (good) terminals, we can use the cromulent ~vterm~ package: #+begin_src emacs-lisp (elpaca vterm) #+end_src ** Treesitter grammar async install Treesitter grammar installation is slow and blocks up the emacs process. The following allows for asyncronous treesitter grammar installation on separate processes: #+begin_src emacs-lisp - (elpaca-wait) (defun ethandl/treesit-install-async (lang) (unless (treesit-language-available-p lang) - (async-start - `(lambda () - ,(async-inject-variables "\\`treesit-language-source-alist\\'") - (treesit-install-language-grammar ',lang)) - 'ignore))) + (ethandl/async-fn-queue-add + `(treesit-install-language-grammar ',lang) + "\\`treesit-language-source-alist\\'"))) #+end_src ** Markdown mode -Emacs comes with ~markdown-ts-mode~, which utilises treesitter to provide highlighting for markdown. This means that we need the treesitter grammar installed: +Emacs comes with ~markdown-ts-mode~, which utilises treesitter to provide highlighting for markdown. +To use this mode, we just install the treesitter grammar(s): #+begin_src emacs-lisp (add-to-list 'treesit-language-source-alist '(markdown "https://github.com/tree-sitter-grammars/tree-sitter-markdown" "split_parser" "tree-sitter-markdown/src")) @@ -459,11 +510,14 @@ Emacs comes with ~markdown-ts-mode~, which utilises treesitter to provide highli (ethandl/treesit-install-async 'markdown-inline) #+end_src ** Emacs Lisp -Not much needs to be done here. For verbosity, I will specify that we want Org to be able to run elisp: +Not much needs to be done here. +For verbosity, I will specify that we want Org babel to be able to evaluate elisp ~src~ blocks: #+begin_src emacs-lisp (add-to-list 'ethandl/org-babel-langs '(emacs-lisp . t)) #+end_src ** Python +There are two python modes installed by default with Emacs. +From my (admittedly limited) experience, ~emacs-ts-mode~ tends to have #+begin_src emacs-lisp (add-to-list 'treesit-language-source-alist '(python "https://github.com/tree-sitter/tree-sitter-python"))