Keeping this separate from my doom-emacs config for now. Loading it with emacs -ql. That's why it's tangling to something that isn't in ~/.config/emacs

Emacs-forge Init

Lexical Binding

;;; -*- lexical-binding: t -*-

Bootstrapping Straight.el

Early-Init

Disables use-package. Needs to be in early-init

  ;;; -*- lexical-binding: t -*-
  (setq package-enable-at-startup-nil)

Bootstrap code

Code required to set-up and use straight.el instead of use-package Installs use-package (for easier configuration) and uses straight.el instead

  (defvar bootstrap-version)
   (let ((bootstrap-file
          (expand-file-name
           "straight/repos/straight.el/bootstrap.el"
           (or (bound-and-true-p straight-base-dir)
               user-emacs-directory)))
         (bootstrap-version 7))
     (unless (file-exists-p bootstrap-file)
       (with-current-buffer
           (url-retrieve-synchronously
            "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
            'silent 'inhibit-cookies)
         (goto-char (point-max))
         (eval-print-last-sexp)))
     (load bootstrap-file nil 'nomessage))

  (straight-use-package 'use-package)
  (setq straight-use-package-by-default t)

Packages

Vertico/Swiper/Orderless/Consult/Marginalia

Completion Stack Plus Swiper I use swiper since it seems like you need to do extra work to make consult-line work like swiper. Future task TODO.

(use-package swiper)
(use-package vertico
  :config
  (setq vertico-cycle t)
  (setq vertico-resize nil)
  (vertico-mode 1))
(use-package orderless
  :custom
  (completion-styles '(orderless basic)))
(use-package consult
  :config
  (add-to-list 'consult-buffer-filter "^\\*"))
(use-package marginalia
  :init
  (marginalia-mode))

Evil and its Evil Ecosystm

Mwahahaha.

(use-package evil
  :init
  (setq evil-want-find-undo t
        undo-limit 9000000
        evil-want-C-u-scroll t
        evil-want-integration t
        evil-want-keybinding nil)
  :config
  (evil-mode 1))

(use-package evil-collection
  :after evil
  :config
  (evil-collection-init))

(use-package evil-goggles)

Modeline

I'd like to configure this some more

  (use-package doom-modeline
    :custom (doom-modeline-height 15)
    :init (doom-modeline-mode 1))

Dashboard

Not sure how I'm going to use this (or if I'm going to use it at all) but throwing it in now to test

  (use-package dashboard
    :ensure t
    :init
    (dashboard-setup-startup-hook))

Binds

General Actual binds are declared later in the file

(use-package general)

Which-key

(use-package which-key
  :init (which-key-mode)
  :diminish which-key-mode
  :config
  (setq which-key-idle-delay 0.3))

Hydra

Provides transient keybindings. This seems very useful, need to investigate more.

(use-package hydra)

(defhydra hydra-text-scale (:timeout 4)
  "scale text"
  ("o" text-scale-increase "in")
  ("k" text-scale-decrease "out")
  ("f" nil "finished" :exit t))

Flycheck

Need to investigate this further but it's useful for at least basic syntax

(use-package flycheck
  :diminish flycheck-mode
  :config
  (flycheck-mode t))

Helpful

Code pulled from dirty-init.el. Investigate if I really want this

;; (straight-use-package 'helpful
;;   :ensure t
;;   :custom
;;   (counsel-describe-function-function #'helpful-callable)
;;   (counsel-describe-variable-function #'helpful-variable)
;;   :bind
;;   ([remap describe-function] . counsel-describe-function)
;;   ([remap describe-command] . helpful-command)
;;   ([remap describe-variable] . counsel-describe-variable)
;;   ([remap describe-key] . helpful-key))

Magit

Is it Mag-it or Maggot?

Assorted other packages

  (use-package vterm)
  (use-package fish-mode)
  (use-package smartparens)

Org and Org-Ecosystem

Lets be honest here, this is the real start of the show

Org

  (use-package org
      :custom
      (org-startup-with-inline-images t)
      (org-startup-indented t)
      (org-startup-folded t))

   (require 'org-tempo)

   (use-package org-modern
      :custom
      (org-modern-star '("◉" "○" "◈" "◇" "*" "◇" "*"))
      (org-ellipsis " ▼")
      (org-auto-align-tags nil)
      (org-tags-column 0)
      (org-fold-catch-invisible-edits 'show-and-error)
      (org-special-ctrl-a/e t)
      (org-insert-heading-respect-content t)
      (org-hide-emphasis-markers t)
      (org-pretty-entities t)
      :config
      (global-org-modern-mode))

   (use-package org-appear
      :hook
      (org-mode . org-appear-mode)
      :custom
      (org-hide-emphasis-markers t)
      (org-appear-autolinks 'just-brackets))

Org-Babel

TODO: Work in progress

Org-autocomplete structure templates. typing < and then a two-letter code will fill in the rest of that entry, eg <el will replace with src emacs-lisp

(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("fi" . "src fish"))
(add-to-list 'org-structure-template-alist '("co" . "src conf-unix"))
(add-to-list 'org-structure-template-alist '("cs" . "src css"))
(add-to-list 'org-structure-template-alist '("js" . "src json"))
(add-to-list 'org-structure-template-alist '("sd" . "src systemd"))
(add-to-list 'org-structure-template-alist '("dc" . "docker-compose-mode"))

Org-Roam

  (use-package org-roam
    :custom
    (org-roam-directory "~/org/roam")
    :config
    (org-roam-db-autosync-enable))

User Interface

Simple Tweaks

This is all simple tweaks and stuff that I prefer. Leaving the menu-bar enabled until ready to go live.

  (scroll-bar-mode -1)
  (tool-bar-mode -1)
  (menu-bar-mode -1)
  (tooltip-mode -1)
  (set-fringe-mode 20)
  (global-visual-line-mode)
  (global-word-wrap-whitespace-mode t)
  (setq inhibit-startup-message t)
  (setq save-interprogram-paste-before-kill t)
  (setq shell-file-name "/bin/fish"
        sh-shell "/bin/fish")
  (setq help-window-select t) ;; switch to help buffer on open
  (global-set-key (kbd "<escape>") 'keyboard-escape-quit) ;; makes ESC a global quit
  (setq recentf-mode t)
  (setq scroll-margin 5)

Line Numbers

Enable lines numbers globally, then disables them for certain modes

(global-display-line-numbers-mode t)
(dolist (mode '(org-mode-hook
                term-mode-hook
                eshell-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 0))))

Theme

I'm basic.

(use-package catppuccin-theme
  :custom
  (catppuccin-flavor 'macchiato))
(load-theme 'catppuccin t)

Font

Set font to Fira Mono. Install all-the-fonts (if not found) TODO: Variable-width-font TODO: Do I need different settings for laptop vs desktop?

(set-face-attribute 'default nil :font "Fira Mono" :height 110)

(use-package all-the-icons
  :if (display-graphic-p)
  :init
  (unless (find-font (font-spec :name "all-the-icons"))
    (all-the-icons-install-fonts t)))

(use-package all-the-icons-dired
  :if (display-graphic-p)
  :hook (dired-mode . all-the-icons-dired-mode))

(use-package all-the-icons-completion
  :if (display-graphic-p)
  :init (all-the-icons-completion-mode)
  :hook (marginalia-mode . all-the-icons-completion-marginalia-setup))

*

Binds

Space as Leader and submenus

  (general-create-definer mei/leader-keys
    :keymaps '(normal insert visual emacs)
    :prefix "SPC"
    :global-prefix "M-SPC")
  (mei/leader-keys
   "f" '(:ignore f :which-key "file")
   "fs" '(save-buffer :which-key "save buffer")
   "ff" '(find-file :which-key "open file")
   "fr" '(consult-recent-file :which-key "recent file")

   "b" '(:ignore b :which-key "buffer")
   "bb" '(consult-buffer :which-key "switch buffer")
   "bk" '(kill-current-buffer :which-key "kill buffer")
   "bl" '(evil-switch-to-windows-last-buffer :which-key "last buffer")
   "bz" '(bury-buffer :which-key "bury buffer")
   "bx" '(scratch-buffer :which-key "scratch buffer")

   "s" '(:ignore s :which-key "search")
   "sb" '(swiper :which-key "search buffer")
   "sm" '(bookmark-jump :which-key "jump to bookmark")
   "sM" '(bookmark-set :which-key "set a bookmark")

   "e" '(:ignore e :which-key "eval")
   "e;" '(eval-expression :which-key "expression")
   "ee" '(eval-last-sexp :which-key "eval last expression")
   "eb" '(eval-buffer :which-key "eval buffer")

   "q" '(:ignore q :which-key "quit and session")
   "qq" '(save-buffers-kill-terminal :which-key "quit emacs")

   "h" '(:ignore h :which-key "help")
   "hf" '(describe-function :which-key "describe function")
   "hk" '(describe-key-briefly :which-key "describe key briefly")
   "hK" '(describe-key :which-key "describe key full")
   "hv" '(describe-variable :which-key "describe variable")

   "c" '(:ignore c :which-key "comments")
   "cr" '(comment-or-uncomment-region :which-key "comment region")
   "cl" '(comment-line :which-key "comment line")

   "w" '(:ignore w :which-key "window")
   "wq" '(evil-quit :which-key "evil-quit")
   "wT" '(tear-off-window :which-key "tear off window")

   "g" '(magit-status :which-key "magit")

   "r" '(:ignore r :which-key "org-roam")
   "r i" '(org-roam-node-insert :which-key "insert org-roam node")
   "r f" '(org-roam-node-find :which-key "find org-roam node")
   "r l" '(org-roam-buffer-toggle :which-key "toggle org-roam buffer")
   )

Global Keybinds

(general-define-key
 :keymaps 'global
 "M-y" 'consult-yank-pop
 "M-Y" 'yank-media
 "M-w" 'kill-ring-save
 "<f2>" 'hydra-text-scale/body)

Other Keybinds

  (general-define-key
   :states 'normal
   "o" 'evil-previous-visual-line
   "k" 'evil-backward-char
   ";" 'evil-forward-char
   "l" 'evil-next-visual-line
   "C-_" 'evil-emacs-state)

  (general-define-key
   :states '(normal insert)
     "C-z" 'evil-undo)

Tangle on Save

I found this function….somewhere online. You have to manually tangle yourself the first time to get the function into your init.el. Once it's loaded then everytime you save this file, it will auto-tangle to the destinations.

(defun efs/org-babel-tangle-config ()
  (when (string-equal (buffer-file-name)
                      (expand-file-name "~/emacs-forge/init.org"))
    ;; Dynamic scoping to the rescue
      (org-babel-tangle)))

(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'efs/org-babel-tangle-config)))