#+TITLE: Literate DOOM Emacs configuration Emacs is a great operating system. But every operating system has 1 essential line of code. For us, this line of code is... (drumroll please) #+begin_src emacs-lisp ;;; $DOOMDIR/config.el -*- lexical-binding: t; -*- #+end_src Almost every ~(use-package!)~ block in this literate configuration has a ~(package!)~ block before it, which is tangled into ~$DOOMDIR/packages.el~. This is how Doom Emacs installs it's packages. * TODO Splash screen Here we load a custom splash screen. I still have to put the splash screen source in this org file, but that'll come later #+begin_src emacs-lisp (load! "splash") (defun +splash-initial-buffer () (splash-screen) (get-buffer "*splash*")) (setq doom-fallback-buffer-name "*splash*" ; make the splash screen be un-killable initial-buffer-choice #'+splash-initial-buffer) ; appear on emacs startup (defadvice! +splash-regenerate-if-missing-a (&rest _) :before #'doom-fallback-buffer (unless (get-buffer "*splash*") (splash-screen))) #+end_src The splash screen doesnt do much, it prints the emacs version and a warranty notice and whatnot. i like it tho! * UI ~How Emacs looks!~ ** Theme Load the directory with additional, local themes This currently mostly loads the emacs port of the Evergarden theme (made by me!) at [[https://git.roughlynamed.net/evergarden.git][git.roughlynamed/net/evergarden.git]], also the fortune-gold theme. The reason i use modus-vivendi instead of my evergarden port is because i dont like evergarden (dont tell the devs though!), seeing it not have an emacs port just made me sad. For this to work, we need modus & ef themes installed. Doric themes are also nice. #+begin_src emacs-lisp :tangle ~/.config/doom/packages.el (package! modus-themes) (package! ef-themes) (package! doric-themes) #+end_src #+begin_src emacs-lisp (add-to-list 'custom-theme-load-path "~/.config/doom/extra-themes/") ;; (setq doom-theme 'modus-vivendi) ;; (setq doom-theme 'doric-oak) (setq doom-theme 'doric-obsidian) ;; (setq doom-theme 'tango) #+end_src By default, Emacs prompts 2 times when loading a theme, this is annoying so im getting rid of it. #+begin_src emacs-lisp (setq custom-safe-themes t) #+end_src ** Font I use the completely not pirated ~Berkeley Mono~ font. I really like it. Sometimes i will use the Commit mono or Cozette! (sometimes!) #+begin_src emacs-lisp (setq doom-font (font-spec :family "Berkeley Mono" :size 13.0)) #+end_src Line numbers! And not relative! I dont like rln, i just dont #+begin_src emacs-lisp (setq display-line-numbers-type t) #+end_src ** Modeline mood-line is a nice & simple modeline for emacs! #+begin_src emacs-lisp :tangle ~/.config/doom/packages.el ;; (package! mood-line) #+end_src #+begin_src emacs-lisp ;; (use-package! mood-line ;; :config ;; (mood-line-mode) ;; :custom ;; (mood-line-glyph-alist mood-line-glyphs-fira-code)) #+end_src The above is commented if the below is in action. I might try out the default Emacs modeline for a bit sometime, or maybe spacemacs' ~spaceline~ ** Minions The default Emacs modeline, by default, spills out EVERY minor & major mode into the modeline. That's kind of yucky, so the ~minions~ package fixes it by hiding most of them & having a menu for which to show. #+begin_src emacs-lisp :tangle ~/.config/doom/packages.el (package! minions) #+end_src Now, let's configure it! #+begin_src emacs-lisp (use-package! minions :config (minions-mode 1)) #+end_src ...Yea that's 'bout it. ** Custom window management I didnt like how in emacs, split windows under ~SPC w s~ just stack, so i made this function to make it dynamic in a fibonnaci-like layout. #+begin_src emacs-lisp (defun my/split-window-dynamically () "Split the selected window, choosing orientation by its shape." (interactive) (select-window (if (> (window-total-width) (* 2 (window-total-height))) (split-window-right) (split-window-below)))) #+end_src Map the function to override ~SPC w s~ #+begin_src emacs-lisp (map! :leader "w s" #'my/split-window-dynamically) #+end_src ** UX ~ UI Scroll margin - when the cursor reaches 3 lines above/below the window bottom/top, the window goes down (this happens in helix automatically, but the margin is 5) #+begin_src emacs-lisp (setq scroll-margin 3) #+end_src ** Breadcrumb Breadcrumb is a package that shows you where you are in a file at the very top of the window. Editing this section of this file, the breadcrumb shows: ~stow/d/.config/doom/config.org : UI~, this is because we are in the UI section of the file. #+begin_src emacs-lisp :tangle ~/.config/doom/packages.el (package! breadcrumb) #+end_src #+begin_src emacs-lisp (use-package! breadcrumb :defer t :hook (prog-mode . breadcrumb-mode) ;; make sure its in programming modes :config (breadcrumb-mode 1)) #+end_src ** Zen the ~zen~ option in Doom Emacs enables ~writeroom~ mode on toggle. ~writeroom~ centers the buffer, makes it bigger and lets you type away without distractions, or read via ~nov.el~ easier. By default, entering ~writeroom~ mode changes the typeface in the buffer. I don't like that, especially when im editing source blocks (e.g here). Let's turn it off. #+begin_src emacs-lisp (setq +zen-mixed-pitch-modes '()) #+end_src ** vertico-carousel ~vertico~ is the equivalent of nvim's ~telescope~ in Emacs. #+begin_quote ~vertico-carousel~ is a display extension for Vertico. It always shows the currently selected candidate on the first line of the candidate list, then displays the following candidates below it, cycling from the end back to the beginning. -- vertico-carousel README #+end_quote #+begin_src emacs-lisp :tangle ~/.config/doom/packages.el (package! vertico-carousel :recipe (:host github :repo "kn66/vertico-carousel")) #+end_src #+begin_src emacs-lisp (use-package! vertico-carousel :config (vertico-carousel-mode 1)) #+end_src * LSP ~M-x vscode~ ** Haskell A custom function that runs the current Haskell file with runghc (interpreter instead of a compiler). #+begin_src emacs-lisp (defun my/hs-eval () (interactive) (let* ((src (buffer-file-name)) (out (file-name-sans-extension src))) (when (zerop (call-process-shell-command (format "runghc %s" src) nil "*runghc-output*")) (let ((buf (make-comint "hs-run" out))) (display-buffer buf))))) #+end_src Hook the function up up to f5 #+begin_src emacs-lisp (add-hook 'haskell-mode-hook (lambda () (local-set-key (kbd "") #'my/hs-eval))) #+end_src ** HTML HTML is a big part of my programming life. There are, however, alot of modes for HTML (html-mode, web-mode, mhtml-mode). These are all good, but the BEST one by far is ~mhtml-ts-mode~, it outcompetes almost all of the above. #+begin_src emacs-lisp (add-to-list 'major-mode-remap-alist '(html-mode . mhtml-ts-mode)) (add-to-list 'major-mode-remap-alist '(mhtml-mode . mhtml-ts-mode)) #+end_src web-mode rescans the whole altered block on every edit, which gets slow on HTML with big inline ~