#+TITLE: Emacs Init File #+AUTHOR: Daniel Ziltener * Initialization ** Requirements Since I am using ~cl-defun~ in this init file, I need to import ~cl-macs~. #+begin_src emacs-lisp (require 'cl-macs) #+end_src ** Personal Information #+NAME: pers-info-table | Name | Mail | |-----------------+---------------------| | Daniel Ziltener | dziltener@lyrion.ch | #+begin_src emacs-lisp :var input=pers-info-table (let ((row (car input))) (setq user-full-name (cl-first row)) (setq user-mail-address (cl-second row))) #+end_src For storage of passwords, I use [[https://www.passwordstore.org/][pass]]: src_emacs-lisp[]{(auth-source-pass-enable)} ** Customizations Since this init file is version controlled, and I set all customizations myself in =use-package= blocks, I want Emacs to use a separate file for authorized =.dir-local= variables and similar stuff. #+begin_src emacs-lisp (setq custom-file "~/.emacs.d/custom.el") (when (file-exists-p custom-file) (load custom-file)) #+end_src ** Package Manager Most packages are being installed using =Guix=, for the few remaining ones that have to be fetched from Git, I use [[https://github.com/progfolio/elpaca][Elpaca]]. #+begin_src emacs-lisp (defvar elpaca-installer-version 0.6) (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" :ref nil :files (:defaults "elpaca-test.el" (:exclude "extensions")) :build (:not elpaca--activate-package))) (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) (build (expand-file-name "elpaca/" elpaca-builds-directory)) (order (cdr elpaca-order)) (default-directory repo)) (add-to-list 'load-path (if (file-exists-p build) build repo)) (unless (file-exists-p repo) (make-directory repo t) (when (< emacs-major-version 28) (require 'subr-x)) (condition-case-unless-debug err (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) ((zerop (call-process "git" nil buffer t "clone" (plist-get order :repo) repo))) ((zerop (call-process "git" nil buffer t "checkout" (or (plist-get order :ref) "--")))) (emacs (concat invocation-directory invocation-name)) ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" "--eval" "(byte-recompile-directory \".\" 0 'force)"))) ((require 'elpaca)) ((elpaca-generate-autoloads "elpaca" repo))) (progn (message "%s" (buffer-string)) (kill-buffer buffer)) (error "%s" (with-current-buffer buffer (buffer-string)))) ((error) (warn "%s" err) (delete-directory repo 'recursive)))) (unless (require 'elpaca-autoloads nil t) (require 'elpaca) (elpaca-generate-autoloads "elpaca" repo) (load "./elpaca-autoloads"))) (add-hook 'after-init-hook #'elpaca-process-queues) (elpaca `(,@elpaca-order)) #+end_src A few additional lines are necessary to integrate it with =use-package=: #+begin_src emacs-lisp (elpaca elpaca-use-package (elpaca-use-package-mode) (setq elpaca-use-package-by-default nil)) (elpaca-wait) #+end_src * Helper Functions Those are meant to reduce code duplication, and add some basic useful features. The first one is a function to create conditional keybindings. #+BEGIN_SRC emacs-lisp (cl-defun conditional-keybind "Creates a keybinding that checks `filter-fn`. If it succeeds, `target-fn` is run, otherwise `fail-fn`. If no fail-fn is given, `self-insert-command` is run instead. `target-fn` and `fail-fn` must both be interactive." (lambda (_prefix) (interactive "P") (if (funcall filter-fn) (call-interactively target-fn) (call-interactively fail-fn)))) #+end_src * Core Emacs Customization :important: Enabled core modes: #+NAME: enabled-core-modes - display-time-mode - global-hl-line-mode - global-prettify-symbols-mode - recentf-mode Disabled core modes: #+NAME: disabled-core-modes - indent-tabs-mode - menu-bar-mode - scroll-bar-mode - tool-bar-mode #+begin_src emacs-lisp :var enabled=enabled-core-modes :var disabled=disabled-core-modes (use-package emacs :custom (completion-cycle-threshold 10) (display-time-mode t) (enable-recursive-minibuffers t) (enable-remote-dir-locals t) (fill-column 100) (global-hl-line-mode t) (global-prettify-symbols-mode t) (indent-tabs-mode nil) (menu-bar-mode nil) (minibuffer-prompt-properties (read-only t cursor-intangible t face minibuffer-prompt)) (read-extended-command-predicate #'command-completion-default-include-p) (recentf-mode t) (scroll-bar-mode nil) (tab-always-indent 'complete) (tool-bar-mode nil) :custom-face (default ((t (:weight bold :height 113 :width normal :family "VictorMono Nerd Font")))) :hook (minibuffer-setup . cursor-intangible-mode) :config (advice-add 'risky-local-variable-p :override #'ignore)) #+end_src ** Sending Mail