summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranck Cuny <franck@fcuny.net>2024-04-06 11:22:57 -0700
committerFranck Cuny <franck@fcuny.net>2024-04-06 11:22:57 -0700
commit7c5780a719565630f58e7751afa8c7e458c49871 (patch)
treef8863ebcbd4a1e551a63374b3fee589affca1393
parentmove some display stuff (diff)
downloademacs.d-7c5780a719565630f58e7751afa8c7e458c49871.tar.gz
a org file is definitely not the way for me
-rw-r--r--abbrevs.el11
-rw-r--r--config/init-buffer.el101
-rw-r--r--config/init-completion.el129
-rw-r--r--config/init-dired.el27
-rw-r--r--config/init-docker.el35
-rw-r--r--config/init-elisp.el19
-rw-r--r--config/init-eshell.el52
-rw-r--r--config/init-file.el50
-rw-r--r--config/init-flymake.el21
-rw-r--r--config/init-git.el97
-rw-r--r--config/init-go.el28
-rw-r--r--config/init-imenu.el23
-rw-r--r--config/init-json.el23
-rw-r--r--config/init-keys.el19
-rw-r--r--config/init-lsp.el28
-rw-r--r--config/init-markdown.el32
-rw-r--r--config/init-modeline.el23
-rw-r--r--config/init-nix.el19
-rw-r--r--config/init-org.el89
-rw-r--r--config/init-osx.el28
-rw-r--r--config/init-programming.el100
-rw-r--r--config/init-project.el27
-rw-r--r--config/init-protobuf.el16
-rw-r--r--config/init-python.el28
-rw-r--r--config/init-rg.el24
-rw-r--r--config/init-ruby.el24
-rw-r--r--config/init-session.el94
-rw-r--r--config/init-shell.el29
-rw-r--r--config/init-snippets.el20
-rw-r--r--config/init-terraform.el20
-rw-r--r--config/init-theme.el66
-rw-r--r--config/init-time.el38
-rw-r--r--config/init-toml.el16
-rw-r--r--config/init-ui.el53
-rw-r--r--config/init-util.el23
-rw-r--r--config/init-whitespace.el33
-rw-r--r--config/init-writing.el19
-rw-r--r--config/init-yaml.el16
-rw-r--r--early-init.el3
-rw-r--r--init.el1157
-rw-r--r--init.org1607
41 files changed, 1534 insertions, 2733 deletions
diff --git a/abbrevs.el b/abbrevs.el
deleted file mode 100644
index 28cd089..0000000
--- a/abbrevs.el
+++ /dev/null
@@ -1,11 +0,0 @@
-;;-*-coding: utf-8;-*-
-(define-abbrev-table 'global-abbrev-table
-  '(
-    ("btw" "by the way" nil :count 2)
-   ))
-
-(define-abbrev-table 'org-mode-abbrev-table
-  '(
-    ("github" "GitHub" nil :count 1)
-   ))
-
diff --git a/config/init-buffer.el b/config/init-buffer.el
new file mode 100644
index 0000000..c8688c6
--- /dev/null
+++ b/config/init-buffer.el
@@ -0,0 +1,101 @@
+;;; init-buffer.el --- Configure buffer -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; buffer related configurations
+
+;;; Code:
+
+(require 'ibuffer)
+(require 'ibuf-ext)
+
+(setq ibuffer-expert t)
+(setq ibuffer-show-empty-filter-groups nil)
+(setq ibuffer-jump-offer-only-visible-buffers t)
+(setq ibuffer-maybe-show-predicates '("^\\*.*\\*$"))
+(setq ibuffer-never-show-predicates '("^ "))
+(setq ibuffer-use-other-window t)
+
+(setq ibuffer-saved-filter-groups
+      '(("default"
+         ("Config" (or
+                    (filename . "world/")
+                    (filename . ".emacs/")))
+
+         ("Programming" (or
+                         (mode . c++-mode)
+                         (mode . c-mode)
+                         (mode . cargo-mode)
+                         (mode . emacs-lisp-mode)
+                         (mode . go-mode)
+                         (mode . java-mode)
+                         (mode . lisp-mode)
+                         (mode . nix-mode)
+                         (mode . python-mode)
+                         (mode . rust-mode)
+                         (mode . sh-mode)
+                         (name . "\\*Cargo")
+                         (name . "\\*Python.*\\*")))
+
+           ("Writing" (or
+                       (mode . plain-tex-mode)
+                       (mode . rst-mode)
+                       (mode . markdown-mode)
+                       (mode . html-mode)
+                       (mode . nxhtml-mode)
+                       (mode . css-mode)))
+
+           ("Org" (or
+                   (mode . org-agenda-mode)
+                   (mode . org-mode)))
+
+           ("Dired" (mode . dired-mode))
+
+           ("Terminals" (mode . term-mode))
+
+           ("Shells" (or
+                      (mode . eshell-mode)
+                      (mode . shell-mode)))
+
+           ("Magit" (or
+                     (mode . magit-mode)
+                     (name . "\\*magit-.*\\*")))
+
+           ("VC" (name . "\\*vc.*\\*"))
+
+           ("Emacs" (name . "^\\*.*\\*$")))))
+
+(add-hook 'ibuffer-mode-hook
+          (lambda ()
+            (ibuffer-auto-mode 1)
+            (ibuffer-switch-to-saved-filter-groups "default")))
+
+(require 'midnight)
+(setq midnight-period (* 3600 6))       ; every 6 hours
+
+(setq clean-buffer-list-delay-general 2           ; every 2 day
+      clean-buffer-list-delay-special (* 3600 3)) ; every 3 hours
+
+(defun my/rename-this-buffer-and-file ()
+  "Renames current buffer and file it is visiting."
+  (interactive)
+  (let ((name (buffer-name))
+        (filename (buffer-file-name))
+        (read-file-name-function 'read-file-name-default))
+    (if (not (and filename (file-exists-p filename)))
+        (error "Buffer '%s' is not visiting a file!" name)
+      (let ((new-name (read-file-name "New name: " filename)))
+        (cond ((get-buffer new-name)
+               (error "A buffer named '%s' already exists!" new-name))
+              (t
+               (rename-file filename new-name 1)
+               (rename-buffer new-name)
+               (set-visited-file-name new-name)
+               (set-buffer-modified-p nil)
+               (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))))
+
+
+(provide 'init-buffer)
+
+;;; init-buffer.el ends here
diff --git a/config/init-completion.el b/config/init-completion.el
new file mode 100644
index 0000000..5a3f785
--- /dev/null
+++ b/config/init-completion.el
@@ -0,0 +1,129 @@
+;;; init-completion.el --- Configure completion -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure completions
+
+;;; Code:
+
+(use-package consult
+  :ensure t
+  :bind (("C-c m"   . consult-mode-command)
+	 ("M-g o"   . consult-org-heading)
+	 ("C-x b"   . consult-buffer)
+	 ("C-x r b" . consult-bookmark)
+	 ("C-x p b" . consult-project-buffer)
+	 ("C-c i"   . consult-imenu)
+	 ("M-g e"   . consult-compile-error)
+	 ("M-g g"   . consult-goto-line)
+	 ("M-g M-g" . consult-goto-line)
+	 ("M-g m"   . consult-mark)
+	 ("M-g k"   . consult-global-mark)))
+
+(use-package corfu
+  :ensure t
+  :demand t
+  :bind (("M-/" . completion-at-point)
+	 :map corfu-map
+	 ("C-n"      . corfu-next)
+	 ("C-p"      . corfu-previous)
+	 ("<return>" . corfu-insert)
+	 ("M-d"      . corfu-info-documentation)
+	 ("M-l"      . corfu-info-location)
+	 ("M-."      . corfu-move-to-minibuffer))
+  :custom
+  ;; Works with `indent-for-tab-command'. Make sure tab doesn't indent when you
+  ;; want to perform completion
+  (tab-always-indent 'complete)
+  (completion-cycle-threshold t)      ; Always show candidates in menu
+
+  (corfu-auto t)
+  (corfu-auto-prefix 2)
+  (corfu-auto-delay 0.25)
+
+  (corfu-min-width 80)
+  (corfu-max-width corfu-min-width)     ; Always have the same width
+  (corfu-cycle t)
+
+  ;; `nil' means to ignore `corfu-separator' behavior, that is, use the older
+  ;; `corfu-quit-at-boundary' = nil behavior. Set this to separator if using
+  ;; `corfu-auto' = `t' workflow (in that case, make sure you also set up
+  ;; `corfu-separator' and a keybind for `corfu-insert-separator', which my
+  ;; configuration already has pre-prepared). Necessary for manual corfu usage with
+  ;; orderless, otherwise first component is ignored, unless `corfu-separator'
+  ;; is inserted.
+  (corfu-quit-at-boundary nil)
+  (corfu-separator ?\s)            ; Use space
+  (corfu-quit-no-match 'separator) ; Don't quit if there is `corfu-separator' inserted
+  (corfu-preview-current 'insert)  ; Preview first candidate. Insert on input if only one
+  (corfu-preselect-first t)        ; Preselect first candidate?
+
+  ;; Other
+  (corfu-echo-documentation nil)        ; Already use corfu-popupinfo
+
+  :init
+  ;; see https://github.com/minad/corfu#completing-in-the-eshell-or-shell
+  (add-hook 'eshell-mode-hook
+            (lambda ()
+              (setq-local corfu-auto nil)
+              (corfu-mode)))
+  :config
+  (global-corfu-mode))
+
+(use-package corfu-popupinfo
+  :after corfu
+  :hook (corfu-mode . corfu-popupinfo-mode)
+  :bind (:map corfu-map
+              ("M-n" . corfu-popupinfo-scroll-up)
+              ("M-p" . corfu-popupinfo-scroll-down)
+              ([remap corfu-show-documentation] . corfu-popupinfo-toggle))
+  :custom
+  (corfu-popupinfo-delay 0.5)
+  (corfu-popupinfo-max-width 70)
+  (corfu-popupinfo-max-height 20)
+  ;; Also here to be extra-safe that this is set when `corfu-popupinfo' is
+  ;; loaded. I do not want documentation shown in both the echo area and in
+  ;; the `corfu-popupinfo' popup.
+  (corfu-echo-documentation nil))
+
+(use-package cape
+  :demand t
+  :ensure t
+  :bind (("C-c . p" . completion-at-point)
+	 ("C-c . h" . cape-history)
+	 ("C-c . f" . cape-file)
+	 ("C-c . a" . cape-abbrev)
+	 ("C-c . l" . cape-line)
+	 ("C-c . w" . cape-dict)
+	 ("C-c . r" . cape-rfc1345))
+  :init
+  ;; Add `completion-at-point-functions', used by `completion-at-point'.
+  (add-to-list 'completion-at-point-functions #'cape-file)
+  (add-to-list 'completion-at-point-functions #'cape-abbrev))
+
+(use-package marginalia
+  :ensure t
+  ;; Either bind `marginalia-cycle' globally or only in the minibuffer
+  :bind (:map minibuffer-local-map
+              ("M-A" . marginalia-cycle))
+  :init
+  ;; Must be in the :init section of use-package such that the mode gets
+  ;; enabled right away. Note that this forces loading the package.
+  (marginalia-mode))
+
+(use-package orderless
+  :demand t
+  :ensure t
+  :custom
+  (completion-styles '(orderless basic))
+  (completion-category-defaults nil))
+
+(use-package vertico
+  :ensure t
+  :config
+  (vertico-mode))
+
+(provide 'init-completion)
+
+;;; init-completion.el ends here
diff --git a/config/init-dired.el b/config/init-dired.el
new file mode 100644
index 0000000..160b86b
--- /dev/null
+++ b/config/init-dired.el
@@ -0,0 +1,27 @@
+;;; init-dired.el --- Configure dired -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configuration for dired-mode
+
+;;; Code:
+
+(require 'dired)
+
+(setq dired-clean-up-buffers-too nil)
+(setq dired-dwim-target t)
+(setq dired-hide-details-hide-information-lines nil)
+(setq dired-hide-details-hide-symlink-targets nil)
+(setq dired-listing-switches "-lah")
+(setq dired-recursive-copies 'always)
+(setq dired-recursive-deletes 'always)
+
+(setq dired-no-confirm
+ '(byte-compile chgrp chmod chown copy hardlink symlink touch))
+
+;; (dired-omit-mode nil t)
+
+(provide 'init-dired)
+
+;;; init-dired.el ends here
diff --git a/config/init-docker.el b/config/init-docker.el
new file mode 100644
index 0000000..4caeea3
--- /dev/null
+++ b/config/init-docker.el
@@ -0,0 +1,35 @@
+;;; init-docker.el --- Docker configuration -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure all things related to docker
+
+;;; Code:
+
+(use-package docker
+  :bind ("C-c d" . docker)
+  :diminish
+  :init
+  (use-package docker-image   :commands docker-images)
+  (use-package docker-volume  :commands docker-volumes)
+  (use-package docker-network :commands docker-containers)
+  (use-package docker-compose :commands docker-compose)
+
+  (use-package docker-container
+    :commands docker-containers
+    :custom
+    (docker-containers-shell-file-name "/bin/bash")
+    (docker-containers-show-all nil)))
+
+(use-package docker-compose-mode
+  :ensure t
+  :mode "docker-compose.*\.yml\\'")
+
+(use-package dockerfile-mode
+  :ensure t
+  :mode "Dockerfile[a-zA-Z.-]*\\'")
+
+(provide 'init-docker)
+
+;;; init-docker.el ends here
diff --git a/config/init-elisp.el b/config/init-elisp.el
new file mode 100644
index 0000000..49f3ab4
--- /dev/null
+++ b/config/init-elisp.el
@@ -0,0 +1,19 @@
+;;; init-elisp.el --- Configure elisp -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure elisp
+
+;;; Code:
+
+(use-package emacs-lisp-mode
+  :bind (:map emacs-lisp-mode-map
+              ("C-c C-r" . eval-region)
+              ("C-c C-d" . eval-defun)
+              ("C-c C-b" . eval-buffer))
+  :hook ((emacs-lisp-mode . flymake-mode)))
+
+(provide 'init-elisp)
+
+;;; init-elisp.el ends here
diff --git a/config/init-eshell.el b/config/init-eshell.el
new file mode 100644
index 0000000..3eb2175
--- /dev/null
+++ b/config/init-eshell.el
@@ -0,0 +1,52 @@
+;;; init-eshell.el --- configure eshell -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure eshell
+
+;;; Code:
+
+(use-package eshell
+  :commands (eshell eshell-command)
+  :custom
+  (eshell-directory-name (emacs-path "eshell"))
+  (eshell-hist-ignoredups t)
+  (eshell-history-size 50000)
+  (eshell-ls-dired-initial-args '("-h"))
+  (eshell-ls-exclude-regexp "~\\'")
+  (eshell-ls-initial-args "-h")
+  (eshell-modules-list
+   '(eshell-alias
+     eshell-basic
+     eshell-cmpl
+     eshell-dirs
+     eshell-glob
+     eshell-hist
+     eshell-ls
+     eshell-pred
+     eshell-prompt
+     eshell-rebind
+     eshell-script
+     eshell-term
+     eshell-unix
+     eshell-xtra))
+  (eshell-prompt-function
+   (lambda nil
+     (concat (abbreviate-file-name (eshell/pwd))
+             (if (= (user-uid) 0)
+                 " # " " $ "))))
+  (eshell-save-history-on-exit t)
+  (eshell-stringify-t nil)
+  (eshell-term-name "ansi")
+
+  :preface
+  (defun eshell-initialize ()
+    (add-hook 'eshell-expand-input-functions #'eshell-spawn-external-command)
+
+  :init
+  (add-hook 'eshell-first-time-mode-hook #'eshell-initialize)))
+
+(provide 'init-eshell)
+
+;;; init-eshell.el ends here
diff --git a/config/init-file.el b/config/init-file.el
new file mode 100644
index 0000000..9c4e803
--- /dev/null
+++ b/config/init-file.el
@@ -0,0 +1,50 @@
+;;; init-file.el --- Configure things related to files -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure things related to files
+
+;;; Code:
+
+(require 'bookmark)
+
+(require 'init-util)
+
+(setq require-final-newline t)
+
+(setq bookmark-default-file (user-data "bookmarks"))
+
+;; Disable backup.
+(setq backup-inhibited t)
+
+;; Disable auto save.
+(setq auto-save-default nil)
+(setq auto-save-list-file-prefix nil)
+
+;; Really, no backups
+(setq make-backup-files nil)
+
+(require 'recentf)
+(recentf-mode 1)
+
+(setq recentf-auto-cleanup 60)
+(setq recentf-exclude
+      '("~\\'" "\\`out\\'" "\\.log\\'" "^/[^/]*:" "\\.el\\.gz\\'" "\\.gz\\'"))
+(setq recentf-max-saved-items 2000)
+(setq recentf-save-file (user-data "recentf"))
+
+(require 'tramp)
+(setq tramp-default-method "ssh")
+(setq tramp-auto-save-directory "~/.cache/emacs/backups")
+(setq tramp-ssh-controlmaster-options "-o ControlMaster=auto -o ControlPath='tramp.%%C'")
+
+(use-package autorevert
+  :custom
+  (auto-revert-use-notify nil)
+  :config
+  (global-auto-revert-mode t))
+
+(provide 'init-file)
+
+;;; init-file.el ends here
diff --git a/config/init-flymake.el b/config/init-flymake.el
new file mode 100644
index 0000000..2dc0550
--- /dev/null
+++ b/config/init-flymake.el
@@ -0,0 +1,21 @@
+;;; init-flymake.el --- Configure flymake -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure flymake
+
+;;; Code:
+
+(require 'flymake)
+
+(setq flymake-start-on-save-buffer t)
+(setq flymake-fringe-indicator-position 'left-fringe)
+(setq flymake-suppress-zero-counters t)
+(setq flymake-proc-compilation-prevents-syntax-check t)
+(setq elisp-flymake-byte-compile-load-path load-path)
+(setq flymake-no-changes-timeout 9999)
+
+(provide 'init-flymake)
+
+;;; init-flymake.el ends here
diff --git a/config/init-git.el b/config/init-git.el
new file mode 100644
index 0000000..4741f35
--- /dev/null
+++ b/config/init-git.el
@@ -0,0 +1,97 @@
+;;; init-git.el --- configure git -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configuration for git
+
+;;; Code:
+
+(require 'init-util)
+
+(use-package magit
+  :defer t
+  :ensure t
+  :bind (("C-x g" . magit-status)
+         ("C-x G" . magit-status-with-prefix))
+  :custom
+  (magit-diff-options nil)
+  (magit-diff-refine-hunk t)
+  (magit-fetch-arguments nil)
+  (magit-log-section-commit-count 10)
+  (magit-pre-refresh-hook nil)
+  (magit-process-popup-time 15)
+  (magit-clone-default-directory "~/workspace/")
+  (magit-section-initial-visibility-alist '((untracked . hide)))
+  :hook (magit-mode . hl-line-mode))
+
+(use-package magit-commit
+  :defer t
+  :config
+  (use-package git-commit
+    :custom
+    (git-commit-major-mode 'markdown-mode)
+    (git-commit-setup-hook
+     '(git-commit-save-message
+       git-commit-turn-on-auto-fill
+       git-commit-turn-on-flyspell
+       bug-reference-mode))))
+
+(use-package magit-status
+  :defer t
+  :config
+  (dolist (func '(magit-insert-unpushed-to-upstream-or-recent
+                  magit-insert-unpulled-from-pushremote
+                  magit-insert-unpulled-from-upstream))
+    (remove-hook 'magit-status-sections-hook func))
+
+  (dolist (func '(magit-insert-diff-filter-header
+                  magit-insert-tags-header))
+    (remove-hook 'magit-status-headers-hook func)))
+
+
+(use-package vc
+  :defer t
+  :custom
+  (vc-command-messages t)
+  (vc-follow-symlinks t))
+
+(use-package git-link
+  :defines git-link-remote-alist
+  :ensure t
+  :bind ("C-c Y" . git-link)
+  :commands (git-link git-link-commit git-link-homepage)
+
+  :custom
+  (git-link-open-in-browser t)
+
+  :preface
+  (defun git-link-fcuny-net (hostname dirname filename branch commit start end)
+    (format "http://git.fcuny.net/%s/tree/%s?id=%s#n%s"
+            (replace-regexp-in-string "^r/\\(.*\\)" "\\1.git" dirname)
+            filename
+            commit
+            start))
+
+  (defun git-link-commit-fcuny-net (hostname dirname commit)
+    (format "http://git.fcuny.net/%s/commit/?id=%s"
+            (replace-regexp-in-string "^r/\\(.*\\)" "\\1.git" dirname)
+            commit))
+
+  :config
+  (add-to-list 'git-link-remote-alist '("git\\.fcuny\\.net" git-link-fcuny-net))
+  (add-to-list 'git-link-commit-remote-alist '("git\\.fcuny\\.net" git-link-commit-fcuny-net))
+
+  ;; sets up roblox git enterprise as a git-link handler
+  (add-to-list 'git-link-remote-alist '("github\\.rblx\\.com" git-link-github))
+  (add-to-list 'git-link-commit-remote-alist '("github\\.rblx\\.com" git-link-commit-github)))
+
+(use-package transient
+  :defer t
+  :custom
+  (transient-history-file (user-data "transient/history.el"))
+  (transient-values-file (user-data "transient/values.el")))
+
+(provide 'init-git)
+
+;;; init-git.el ends here
diff --git a/config/init-go.el b/config/init-go.el
new file mode 100644
index 0000000..daabb2b
--- /dev/null
+++ b/config/init-go.el
@@ -0,0 +1,28 @@
+;;; init-go.el --- Configure go related things -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; go-mode and friends
+
+;;; Code:
+
+(use-package go-mode
+  :ensure t
+  :defer t
+  :hook ((go-mode . tree-sitter-hl-mode)
+         (go-mode . eglot-ensure)
+         (go-mode . (lambda () (setq tab-width 4)))
+         (go-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t))))
+  :bind (:map go-mode-map
+              ("C-c C-c" . compile)))
+
+(use-package gotest
+  :ensure t
+  :after go-mode
+  :custom
+  (go-test-verbose t))
+
+(provide 'init-go)
+
+;;; init-go.el ends here
diff --git a/config/init-imenu.el b/config/init-imenu.el
new file mode 100644
index 0000000..24f71f9
--- /dev/null
+++ b/config/init-imenu.el
@@ -0,0 +1,23 @@
+;;; init-imenu.el --- Configure imenu -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure imenu
+
+;;; Code:
+
+;;; imenu
+(with-eval-after-load 'imenu
+  ;; Recenter buffer after jumping.
+  (add-hook
+   'imenu-after-jump-hook
+   (lambda () (recenter (max scroll-margin (/ (window-height) 3)))))
+
+  (setq-default imenu-auto-rescan t)
+  (setq-default imenu-auto-rescan-maxout (* 1024 1024))
+  (setq-default imenu--rescan-item '("" . -99)))
+
+(provide 'init-imenu)
+
+;;; init-imenu.el ends here
diff --git a/config/init-json.el b/config/init-json.el
new file mode 100644
index 0000000..7f0cfcb
--- /dev/null
+++ b/config/init-json.el
@@ -0,0 +1,23 @@
+;;; init-json.el --- Configure JSON -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure json-mode and jq-mode
+
+;;; Code:
+
+(use-package json-mode
+  :mode "\\.json\\'")
+
+(use-package json-reformat
+  :ensure t
+  :after json-mode)
+
+(use-package jq-mode
+  :ensure t
+  :mode "\\.jq\\'")
+
+(provide 'init-json)
+
+;;; init-json.el ends here
diff --git a/config/init-keys.el b/config/init-keys.el
new file mode 100644
index 0000000..a3686fe
--- /dev/null
+++ b/config/init-keys.el
@@ -0,0 +1,19 @@
+;;; init-keys.el --- Configure key bindings -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure key bindings
+
+;;; Code:
+
+(use-package which-key
+  :demand t
+  :diminish
+  :ensure t
+  :config
+  (which-key-mode))
+
+(provide 'init-keys)
+
+;;; init-keys.el ends here
diff --git a/config/init-lsp.el b/config/init-lsp.el
new file mode 100644
index 0000000..bad227d
--- /dev/null
+++ b/config/init-lsp.el
@@ -0,0 +1,28 @@
+;;; init-lsp.el --- Configure LSP integration -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure LSP integration
+
+;;; Code:
+
+(use-package eglot
+  :ensure t
+  :after yasnippet
+  :bind (:map eglot-mode-map
+              ("C-c l a" . eglot-code-actions)
+              ("C-c l r" . eglot-rename))
+  :config
+  (setq-default eglot-workspace-configuration
+                '((gopls
+		   (usePlaceholders . t)
+		   (staticcheck . t)
+		   (completeUnimported . t))))
+
+  ;; uses https://github.com/oxalica/nil for the LSP server instead of rnix
+  (add-to-list 'eglot-server-programs '(nix-mode . ("nixd"))))
+
+(provide 'init-lsp)
+
+;;; init-lsp.el ends here
diff --git a/config/init-markdown.el b/config/init-markdown.el
new file mode 100644
index 0000000..07e927d
--- /dev/null
+++ b/config/init-markdown.el
@@ -0,0 +1,32 @@
+;;; init-markdown.el --- Configure markdown -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configuration related to markdown
+
+;;; Code:
+
+(use-package markdown-mode
+  :mode (("\\`README\\.md\\'" . gfm-mode)
+         ("\\.md\\'"          . markdown-mode)
+         ("\\.markdown\\'"    . markdown-mode))
+  :custom
+  (markdown-command "pandoc -f markdown_github+smart")
+  (markdown-command-needs-filename t)
+  (markdown-enable-math t)
+  (markdown-open-command "marked")
+  :init
+  (setq markdown-command "multimarkdown"))
+
+(use-package markdown-preview-mode
+  :ensure t
+  :after markdown-mode
+  :config
+  (setq markdown-preview-stylesheets
+	(list (concat "https://github.com/dmarcotte/github-markdown-preview/"
+		      "blob/master/data/css/github.css"))))
+
+(provide 'init-markdown)
+
+;;; init-markdown.el ends here
diff --git a/config/init-modeline.el b/config/init-modeline.el
new file mode 100644
index 0000000..9d3c59a
--- /dev/null
+++ b/config/init-modeline.el
@@ -0,0 +1,23 @@
+;;; init-modeline.el --- configure the modeline -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure the modeline
+
+;;; Code:
+
+(require 'diminish)
+(require 'time)
+
+;; show column number in the mode line
+(setq column-number-mode t)
+
+(setq display-time-24hr-format t
+      display-time-interval 60
+      display-time-format "%H:%M %d.%m"
+      display-time-default-load-average nil)
+
+(provide 'init-modeline)
+
+;;; init-modeline.el ends here
diff --git a/config/init-nix.el b/config/init-nix.el
new file mode 100644
index 0000000..d0e50c7
--- /dev/null
+++ b/config/init-nix.el
@@ -0,0 +1,19 @@
+;;; init-nix.el --- Configure nix -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; All nix related things
+
+;;; Code:
+
+(use-package nix-mode
+  :ensure t
+  :hook ((nix-mode . eglot-ensure)
+         (nix-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t))))
+  :custom
+  (nix-indent-function 'nix-indent-line))
+
+(provide 'init-nix)
+
+;;; init-nix.el ends here
diff --git a/config/init-org.el b/config/init-org.el
new file mode 100644
index 0000000..9f5c4a0
--- /dev/null
+++ b/config/init-org.el
@@ -0,0 +1,89 @@
+;;; init-org.el --- configure things related to org-mode -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure things related to org-mode
+
+;;; Code:
+
+(use-package org
+  :hook
+  (org-mode . turn-on-flyspell)
+  (org-mode . visual-line-mode)
+  (org-mode . org-indent-mode)
+  :custom
+    ;;; general settings
+  (org-startup-folded t)
+  (org-startup-indented t)
+  (org-hide-emphasis-markers t)
+  (org-hide-leading-stars t)
+  (org-pretty-entities t)
+  (org-return-follows-link t)
+  (org-startup-with-inline-images t)
+  (org-export-backends '(html md))
+  (org-imenu-depth 4)
+  (org-insert-heading-respect-content t)
+  (org-outline-path-complete-in-steps nil)
+  (org-src-fontify-natively t)
+  (org-src-preserve-indentation t)
+  (org-src-tab-acts-natively t)
+  (org-src-window-setup 'current-window)
+  (org-yank-adjusted-subtrees t)
+  (org-structure-template-alist
+   '(("s" . "src")
+     ("E" . "src emacs-lisp")
+     ("p" . "src python")
+     ("e" . "example")
+     ("q" . "quote")
+     ("V" . "verbatim")))
+  :config
+  (font-lock-add-keywords 'org-mode
+                          '(("^ *\\(-\\) "
+                             (0 (ignore (compose-region (match-beginning 1) (match-end 1) "•")))))))
+
+(use-package org-bullets
+  :ensure t
+  :hook (org-mode . org-bullets-mode))
+
+(use-package org-auto-tangle
+  :ensure t
+  :hook (org-mode . org-auto-tangle-mode))
+
+(use-package org-babel
+  :no-require t
+  :after (org)
+  :config
+  (org-babel-do-load-languages
+   'org-babel-load-languages
+   '((python     . t)
+     (emacs-lisp . t)
+     (calc       . t)
+     (shell      . t)
+     (sql        . t)
+     (dot        . t)))
+
+  (remove-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory)
+
+  (advice-add 'org-babel-edit-prep:emacs-lisp :after
+              #'(lambda (_info) (run-hooks 'emacs-lisp-mode-hook))))
+
+(use-package ox-gfm
+  :ensure t
+  :after org)
+
+(use-package ox-md
+  :after org)
+
+(use-package ox-pandoc
+  :ensure t
+  :after org
+  :preface
+  (defun markdown-to-org-region (start end)
+    "Convert region from markdown to org, replacing selection"
+    (interactive "r")
+    (shell-command-on-region start end "pandoc -f markdown -t org" t t)))
+
+(provide 'init-org)
+
+;;; init-org.el ends here
diff --git a/config/init-osx.el b/config/init-osx.el
new file mode 100644
index 0000000..a9fe148
--- /dev/null
+++ b/config/init-osx.el
@@ -0,0 +1,28 @@
+;;; init-osx.el --- configure osx -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure osx
+
+;;; Code:
+
+(when (memq window-system '(mac ns))
+  (add-to-list 'default-frame-alist '(fullscreen . maximized))
+  (add-to-list 'default-frame-alist '(ns-appearance . nil))
+  (add-to-list 'default-frame-alist '(ns-transparent-titlebar . nil))
+  (when (boundp 'ns-use-native-fullscreen)
+    (setq ns-use-native-fullscreen nil))
+  (when (boundp 'mac-allow-anti-aliasing)
+    (setq mac-allow-anti-aliasing t)))
+
+(use-package exec-path-from-shell
+  :ensure t
+  :demand t
+  :if (memq window-system '(mac ns))
+  :config
+  (exec-path-from-shell-initialize))
+
+(provide 'init-osx)
+
+;;; init-osx.el ends here
diff --git a/config/init-programming.el b/config/init-programming.el
new file mode 100644
index 0000000..984485b
--- /dev/null
+++ b/config/init-programming.el
@@ -0,0 +1,100 @@
+;;; init-programming.el --- Configure things related to programming -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure things related to programming
+
+;;; Code:
+
+(require 'compile)
+(setq compilation-always-kill t)
+;; Don't freeze when process reads from stdin
+(setq compilation-disable-input t)
+(setq compilation-ask-about-save nil)
+(setq compilation-context-lines 10)
+(setq compilation-scroll-output 'first-error)
+(setq compilation-skip-threshold 2)
+(setq compilation-window-height 100)
+
+(use-package eldoc
+  :diminish
+  :hook ((c-mode-common emacs-lisp-mode) . eldoc-mode)
+  :custom
+  (eldoc-idle-delay 1)
+  (eldoc-documentation-strategy #'eldoc-documentation-default)
+  (eldoc-echo-area-use-multiline-p 3)
+  (eldoc-echo-area-prefer-doc-buffer 'maybe)
+  (eldoc-echo-area-display-truncation-message nil))
+
+(use-package indent
+  :commands indent-according-to-mode
+  :custom
+  (tab-always-indent 'complete))
+
+(use-package tree-sitter
+  :ensure t
+  :config
+  (global-tree-sitter-mode))
+
+(use-package tree-sitter-langs
+  :after tree-sitter
+  :ensure t)
+
+(use-package direnv
+  :ensure t
+  :custom
+  (direnv-always-show-summary nil)
+  :config
+  (direnv-mode))
+
+(use-package restclient
+  :ensure t
+  :mode ("\\.rest\\'" . restclient-mode))
+
+(setq prettify-symbols-unprettify-at-point 'right-edge)
+
+
+(defun my/github-code-search ()
+  "Search code on github for a given language."
+  (interactive)
+  (let ((language (completing-read
+                   "Language: "
+                   '("Emacs Lisp" "Python"  "Go" "Nix")))
+        (code (read-string "Code: ")))
+    (browse-url
+     (concat "https://github.com/search?lang=" language
+             "&type=code&q=" code))))
+
+(defun my/work-code-search ()
+  "Search code on sourcegraph for a given language."
+  (interactive)
+  (let ((language (completing-read
+                   "Language: "
+                   '("Ruby" "Python"  "Go")))
+        (code (read-string "Code: ")))
+    (browse-url
+     (concat "https://sourcegraph.rbx.com/search?q=context:global+lang:" language
+             "+" code))))
+
+
+(require 'init-elisp)
+(require 'init-lsp)
+(require 'init-go)
+(require 'init-nix)
+(require 'init-python)
+(require 'init-ruby)
+
+(require 'init-flymake)
+
+(require 'init-shell)
+(require 'init-json)
+(require 'init-terraform)
+(require 'init-toml)
+(require 'init-yaml)
+
+(require 'init-docker)
+
+(provide 'init-programming)
+
+;;; init-programming.el ends here
diff --git a/config/init-project.el b/config/init-project.el
new file mode 100644
index 0000000..34928c5
--- /dev/null
+++ b/config/init-project.el
@@ -0,0 +1,27 @@
+;;; init-project.el --- Configure project -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure project
+
+;;; Code:
+
+(require 'init-util)
+
+(require 'project)
+
+(with-eval-after-load 'project
+  (define-key project-prefix-map (kbd "v") 'magit-status))
+
+(global-set-key (kbd "C-x p b") 'consult-project-buffer)
+
+(setq project-switch-commands
+      (append '((magit-status "Magit status"))
+              project-switch-commands))
+
+(setq-default project-list-file (user-data "projects.eld"))
+
+(provide 'init-project)
+
+;;; init-project.el ends here
diff --git a/config/init-protobuf.el b/config/init-protobuf.el
new file mode 100644
index 0000000..1af464b
--- /dev/null
+++ b/config/init-protobuf.el
@@ -0,0 +1,16 @@
+;;; init-protobuf.el --- configure protocol buffer -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure protobuf
+
+;;; Code:
+
+(use-package protobuf-mode
+  :ensure t
+  :mode "\\.proto\\'")
+
+(provide 'init-protobuf.el)
+
+;;; init-protobuf.el ends here
diff --git a/config/init-python.el b/config/init-python.el
new file mode 100644
index 0000000..0927dd2
--- /dev/null
+++ b/config/init-python.el
@@ -0,0 +1,28 @@
+;;; init-python.el --- Configure python -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; All python related things
+
+;;; Code:
+
+(use-package python-mode
+  :hook ((python-mode . tree-sitter-hl-mode)
+         (python-mode . eglot-ensure))
+  :interpreter "python"
+  :bind (:map python-mode-map
+              ("C-c c")
+              ("C-c C-z" . python-shell)))
+
+(use-package blacken
+  :ensure t
+  :hook (python-mode . blacken-mode))
+
+(use-package py-isort
+  :ensure t
+  :commands (py-isort-buffer py-isort-region))
+
+(provide 'init-python)
+
+;;; init-python.el ends here
diff --git a/config/init-rg.el b/config/init-rg.el
new file mode 100644
index 0000000..df7cdfe
--- /dev/null
+++ b/config/init-rg.el
@@ -0,0 +1,24 @@
+;;; init-rg.el --- configure ripgrep -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure ripgrep
+
+;;; Code:
+
+(use-package rg
+  :ensure t
+  :custom ((rg-group-result t)
+           (rg-show-columns t)
+           (rg-align-line-number-field-length 3)
+           (rg-align-column-number-field-length 3)
+           (rg-align-line-column-separator "#")
+           (rg-align-position-content-separator "|")
+           (rg-hide-command nil)
+           (rg-align-position-numbers t)
+           (rg-command-line-flags '("--follow"))))
+
+(provide 'init-rg)
+
+;;; init-rg.el ends here
diff --git a/config/init-ruby.el b/config/init-ruby.el
new file mode 100644
index 0000000..fc33a48
--- /dev/null
+++ b/config/init-ruby.el
@@ -0,0 +1,24 @@
+;;; init-ruby.el --- configure ruby -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure ruby
+
+;;; Code:
+
+(use-package ruby-mode
+  :mode "\\.rb\\'"
+  :interpreter "ruby"
+  :bind (:map ruby-mode-map
+              ("<return>" . my-ruby-smart-return))
+  :preface
+  (defun my-ruby-smart-return ()
+    (interactive)
+    (when (memq (char-after) '(?\| ?\" ?\'))
+      (forward-char))
+    (call-interactively 'newline-and-indent)))
+
+(provide 'init-ruby)
+
+;;; init-ruby.el ends here
diff --git a/config/init-session.el b/config/init-session.el
new file mode 100644
index 0000000..56f8b9b
--- /dev/null
+++ b/config/init-session.el
@@ -0,0 +1,94 @@
+;;; init-session.el --- configure session -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure sesson
+
+;;; Code:
+
+(require 'init-util)
+
+(setq create-lockfiles nil)                      ;; don't use a lock file
+(setq confirm-kill-emacs #'yes-or-no-p)          ;; ask before killing emacs
+(setq minibuffer-message-timeout 0.5)            ;; How long to display an echo-area message
+
+(setq ring-bell-function 'ignore)                ;; really no bell
+(setq tab-always-indent 'complete)               ;; when using TAB, always indent
+(setq visible-bell nil)                          ;; no bell
+
+(setq electric-pair-mode 1)                      ;; matches parens and brackets
+(setq indent-tabs-mode nil)                      ;; turn off tab indentation
+
+(setq delete-by-moving-to-trash t)               ;; delete files by moving them to the trash
+
+;; bytecomp.el
+(setq byte-compile-verbose nil)
+
+;; startup.el
+(setq initial-buffer-choice t)
+(setq initial-major-mode 'fundamental-mode)
+(setq initial-scratch-message "")
+
+(setq user-full-name "Franck Cuny")
+(setq user-mail-address "franck@fcuny.net")
+(setq add-log-mailing-address "franck@fcuny.net")
+
+(setq history-length 200)
+(setq history-delete-duplicates t)
+(setq completion-ignored-extensions
+      '(".class"
+        ".cp"
+        ".elc"
+        ".fmt"
+        ".git/"
+        ".pyc"
+        ".so"
+        "~"))
+
+;; paragraphs.el
+(setq sentence-end-double-space nil)
+
+;; switch to view-mode whenever you are in a read-only buffer (e.g.
+;; switched to it using C-x C-q).
+(setq view-read-only t)
+
+;; window.el
+(setq switch-to-buffer-preserve-window-point t)
+
+;; warnings.el
+(setq warning-minimum-log-level :error)
+
+(use-package savehist
+  :unless noninteractive
+  :custom
+  (savehist-additional-variables
+   '(file-name-history
+     kmacro-ring
+     compile-history
+     compile-command))
+  (savehist-autosave-interval 60)
+  (savehist-file (user-data "history"))
+  (savehist-ignored-variables
+   '(load-history
+     flyspell-auto-correct-ring
+     org-roam-node-history
+     magit-revision-history
+     org-read-date-history
+     query-replace-history
+     yes-or-no-p-history
+     kill-ring))
+  (savehist-mode t)
+  :config
+  (savehist-mode 1))
+
+(use-package saveplace
+  :unless noninteractive
+  :custom
+  (save-place-file (user-data "places"))
+  :config
+  (save-place-mode 1))
+
+(provide 'init-session)
+
+;;; init-session.el ends here
diff --git a/config/init-shell.el b/config/init-shell.el
new file mode 100644
index 0000000..643877b
--- /dev/null
+++ b/config/init-shell.el
@@ -0,0 +1,29 @@
+;;; init-shell.el --- configure shell -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure shell
+
+;;; Code:
+
+(use-package sh-script
+  :defer t
+  :preface
+  (defvar sh-script-initialized nil)
+
+  (defun initialize-sh-script ()
+    (unless sh-script-initialized
+      (setq sh-script-initialized t)
+      (info-lookup-add-help :mode 'shell-script-mode
+                            :regexp ".*"
+                            :doc-spec '(("(bash)Index")))))
+  :init
+  (add-hook 'shell-mode-hook #'initialize-sh-script))
+
+(add-hook 'after-save-hook
+              #'executable-make-buffer-file-executable-if-script-p)
+
+(provide 'init-shell)
+
+;;; init-shell.el ends here
diff --git a/config/init-snippets.el b/config/init-snippets.el
new file mode 100644
index 0000000..7c6a83e
--- /dev/null
+++ b/config/init-snippets.el
@@ -0,0 +1,20 @@
+;;; init-snippets.el --- configure snippets -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure snippets
+
+;;; Code:
+
+(use-package yasnippet
+  :ensure t
+  :defer t
+  :diminish
+  :hook ((prog-mode . yas-minor-mode))
+  :config
+  (yas-reload-all))
+
+(provide 'init-snippets)
+
+;;; init-snippets.el ends here
diff --git a/config/init-terraform.el b/config/init-terraform.el
new file mode 100644
index 0000000..4012f0c
--- /dev/null
+++ b/config/init-terraform.el
@@ -0,0 +1,20 @@
+;;; init-terraform.el --- Configure terraform -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; terraform and related formats
+
+;;; Code:
+
+(use-package terraform-mode
+  :ensure t
+  :mode "\.tf\\'")
+
+(use-package hcl-mode
+  :ensure t
+  :mode "\.nomad\\'")
+
+(provide 'init-terraform)
+
+;;; init-terraform.el ends here
diff --git a/config/init-theme.el b/config/init-theme.el
new file mode 100644
index 0000000..5c938e7
--- /dev/null
+++ b/config/init-theme.el
@@ -0,0 +1,66 @@
+;;; init-theme.el --- configure the theme -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure the theme
+
+;;; Code:
+
+;; use various monaspace fonts
+;; https://monaspace.githubnext.com
+(set-face-attribute 'default nil
+                    :font "Monaspace Neon"
+                    :height 150)
+
+(set-face-attribute 'fixed-pitch nil
+                    :font "Monaspace Neon"
+                    :height 150)
+
+(set-face-attribute 'variable-pitch nil
+                    :font "Monaspace Radon"
+                    :height 150)
+
+(custom-set-faces '
+ (font-lock-comment-face ((t (:font "Monaspace Radon" :italic t :height 1.0)))))
+
+(use-package modus-themes
+  :ensure t
+  :custom
+  ;; Syntax Highlighting
+  (modus-themes-bold-constructs t)
+  (modus-operandi-palette-overrides '((comment red-faint)
+                                      (string "#101010")
+                                      (bg-main "#FFFCF6")))
+
+  (modus-themes-italic-constructs t)
+
+  ;; Use mixed fonts
+  (modus-themes-mixed-fonts t)
+  (modus-themes-variable-pitch-ui t)
+
+  ;; Enhance minibuffer completions
+  (modus-themes-prompts '(italic bold))
+  (modus-themes-completions '((matches . (extrabold))
+                              (selection . (semibold italic text-also))))
+
+  ;; Org Mode
+  ;;; Make headings in org files more distinct
+  (modus-themes-headings '((t . (background bold rainbow 1))))
+  ;;; Tint the background of code blocks in org files
+  (modus-themes-org-blocks 'tinted-background)
+  ;;; Make tags less colorful and tables look the same as
+  ;;; the default foreground.
+  (prose-done cyan-cooler)
+  (prose-tag fg-dim)
+  (prose-table fg-main)
+
+  ;; Make the fringe more intense
+  (modus-themes-common-palette-overrides '((fringe bg-active)))
+
+  :config
+  (load-theme 'modus-operandi t))
+
+(provide 'init-theme)
+
+;;; init-theme.el ends here
diff --git a/config/init-time.el b/config/init-time.el
new file mode 100644
index 0000000..a6932aa
--- /dev/null
+++ b/config/init-time.el
@@ -0,0 +1,38 @@
+;;; init-time.el --- configure time -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure time
+
+;;; Code:
+
+(require 'time)
+
+(setq display-time-mode t)
+(setq display-time-24hr-format t)
+(setq display-time-day-and-date t)
+(setq display-time-default-load-average nil)
+(setq world-clock-list t)
+(setq world-clock-timer-enable t)
+(setq world-clock-timer-second 60)
+;; UTC      => 02:42 +0000  Wednesday 20 April
+;; Berkeley => 19:42 -0700  Tuesday 19 April
+(setq world-clock-time-format "%R %z  %A %d %B")
+(setq zoneinfo-style-world-list '(("UTC" "UTC")
+                             ("America/Los_Angeles" "Berkeley")
+                             ("America/Denver" "Mountain Time")
+                             ("America/Chicago" "Central Time")
+                             ("America/New_York" "New York")
+                             ("Europe/London" "London")
+                             ("Europe/Paris" "Paris")))
+
+(add-to-list 'display-buffer-alist '("\\*wclock\\*"
+                                     (display-buffer-in-side-window)
+                                     (side . left)
+                                     (slot . 0)
+                                     (window-width . 0.35)))
+
+(provide 'init-time)
+
+;;; init-time.el ends here
diff --git a/config/init-toml.el b/config/init-toml.el
new file mode 100644
index 0000000..28b56db
--- /dev/null
+++ b/config/init-toml.el
@@ -0,0 +1,16 @@
+;;; init-toml.el --- Configure TOML related things -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; For TOML
+
+;;; Code:
+
+(use-package toml-mode
+  :defer t
+  :ensure t)
+
+(provide 'init-toml)
+
+;;; init-toml.el ends here
diff --git a/config/init-ui.el b/config/init-ui.el
new file mode 100644
index 0000000..04ab67f
--- /dev/null
+++ b/config/init-ui.el
@@ -0,0 +1,53 @@
+;;; init-ui.el --- User interface config. -*- lexical-binding: t -*-
+
+;;; Commentary:
+
+;; User interface settings.
+
+;;; Code:
+
+;; Don't say anything on mode-line mouseover.
+(setq mode-line-default-help-echo nil)
+
+;; Keep cursors and highlights in current window only.
+(setq cursor-in-non-selected-windows nil)
+
+;; Don't highlight inactive windows.
+(setq highlight-nonselected-windows nil)
+
+;; Use y-or-n
+(setq use-short-answers t)
+
+;; Use UTF-8 everywhere
+(prefer-coding-system       'utf-8)
+(set-default-coding-systems 'utf-8)
+(set-terminal-coding-system 'utf-8)
+(set-keyboard-coding-system 'utf-8)
+
+(show-paren-mode 1)
+(setq show-paren-delay 0)
+(setq show-paren-highlight-openparen t)
+(setq show-paren-when-point-inside-paren t)
+(setq show-paren-when-point-in-periphery t)
+
+(require 'fringe)
+;; no fringe on the right side
+(set-fringe-mode '(8 . 0))
+
+;; Disable bidirectional text support for slight performance bonus.
+(setq bidi-display-reordering nil)
+
+(setq window-divider-default-bottom-width 1)
+(setq window-divider-default-places 'bottom-only)
+
+;; empty scratch buffer
+(setq initial-scratch-message "")
+
+;; scroll 5 lines at a time
+(setq next-screen-context-lines 5)
+
+;; cursor is a horizontal bar
+(setq cursor-type 'box)
+
+(provide 'init-ui)
+;;; init-ui.el ends here
diff --git a/config/init-util.el b/config/init-util.el
new file mode 100644
index 0000000..71b862e
--- /dev/null
+++ b/config/init-util.el
@@ -0,0 +1,23 @@
+;;; init-util.el --- Util functions and variables -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; util functions and variables
+
+;;; Code:
+
+(defsubst emacs-path (path)
+  "The PATH where Emacs configuration is loaded from."
+  (expand-file-name path user-emacs-directory))
+
+(defconst user-data-directory
+  (emacs-path "data"))
+
+(defun user-data (dir)
+  "Concat DIR under the user's directory."
+  (expand-file-name dir user-data-directory))
+
+(provide 'init-util)
+
+;;; init-util.el ends here
diff --git a/config/init-whitespace.el b/config/init-whitespace.el
new file mode 100644
index 0000000..14533ad
--- /dev/null
+++ b/config/init-whitespace.el
@@ -0,0 +1,33 @@
+;;; init-whitespace.el --- configure whitespace -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; configure whitespace
+
+;;; Code:
+
+(use-package whitespace
+  :diminish (global-whitespace-mode
+             whitespace-mode
+             whitespace-newline-mode)
+  :commands (whitespace-buffer
+             whitespace-cleanup
+             whitespace-mode
+             whitespace-turn-off)
+  :init
+  (dolist (hook '(prog-mode-hook text-mode-hook))
+    (add-hook hook #'whitespace-mode))
+  :custom
+  (whitespace-auto-cleanup t t)
+  (whitespace-rescan-timer-time nil t)
+  (whitespace-silent t t)
+  (whitespace-style '(face trailing space-before-tab))
+  :defines
+  (whitespace-auto-cleanup
+   whitespace-rescan-timer-time
+   whitespace-silent))
+
+(provide 'init-whitespace)
+
+;;; init-whitespace.el ends here
diff --git a/config/init-writing.el b/config/init-writing.el
new file mode 100644
index 0000000..e60f030
--- /dev/null
+++ b/config/init-writing.el
@@ -0,0 +1,19 @@
+;;; init-writing.el --- Configure things related to writing -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; Configure things related to writing
+
+;;; Code:
+
+(require 'init-markdown)
+
+(require 'ispell)
+(setq ispell-program-name (executable-find "aspell"))
+(setq ispell-dictionary "en_US")
+(setq ispell-extra-args '("--camel-case"))
+
+(provide 'init-writing)
+
+;;; init-writing.el ends here
diff --git a/config/init-yaml.el b/config/init-yaml.el
new file mode 100644
index 0000000..0a460e6
--- /dev/null
+++ b/config/init-yaml.el
@@ -0,0 +1,16 @@
+;;; init-yaml.el --- Configure YAML -*- lexical-binding: t -*-
+;; Author: Franck Cuny <franck@fcuny.net>
+
+;;; Commentary:
+
+;; YAML related configurations
+
+;;; Code:
+
+(use-package yaml-mode
+  :ensure t
+  :mode "\\.ya?ml\\'")
+
+(provide 'init-yaml)
+
+;;; init-yaml.el ends here
diff --git a/early-init.el b/early-init.el
index 0312190..870eb01 100644
--- a/early-init.el
+++ b/early-init.el
@@ -21,6 +21,9 @@
 ;; increase font size
 (set-face-attribute 'default nil :height 130)
 
+(setq init-file-debug t)
+(setq debug-on-error init-file-debug)
+
 (add-hook
  'emacs-startup-hook
  (lambda (&rest _)
diff --git a/init.el b/init.el
index cd365c0..de81c2b 100644
--- a/init.el
+++ b/init.el
@@ -6,64 +6,20 @@
 
 (defconst emacs-start-time (current-time))
 
-(defun report-time-since-load (&optional suffix)
-  (message "Loading init...done (%.3fs)%s"
-	   (float-time (time-subtract (current-time) emacs-start-time))
-	   suffix))
+(defun report-time-since-load ()
+  "Report how long it takes to load my Emacs configuration."
+  (message "[after-init ]Loading init...done (%.3fs)"
+	   (float-time (time-subtract (current-time) emacs-start-time))))
 
-(add-hook 'after-init-hook
-	  #'(lambda () (report-time-since-load " [after-init]"))
-	  t)
+(add-hook 'after-init-hook #'(lambda () (report-time-since-load)) t)
 
-(fset 'yes-or-no-p 'y-or-n-p)          ; replace yes/no prompts with y/n
-
-;; UTF-8 Everywhere
-(prefer-coding-system 'utf-8-unix)
-(set-default-coding-systems 'utf-8)
-(set-terminal-coding-system 'utf-8)
-(set-keyboard-coding-system 'utf-8)
-(setq locale-coding-system 'utf-8)
-
-;; no backups
-;; Disable backup.
-(setq backup-inhibited t)
-;; Disable auto save.
-(setq auto-save-default nil)
-(setq auto-save-list-file-prefix nil)
-;; really no backups
-(setq make-backup-files nil)
-
-;; Don't say anything on mode-line mouseover.
-(setq mode-line-default-help-echo nil)
-;; Keep cursors and highlights in current window only.
-(setq cursor-in-non-selected-windows nil)
-;; Don't highlight inactive windows.
-(setq highlight-nonselected-windows nil)
-;; Disable bidirectional text support for slight performance bonus.
-(setq bidi-display-reordering nil)
-
-(setq load-prefer-newer t)
-(setq init-file-debug t)
-
-;;; imenu
-(with-eval-after-load 'imenu
-  ;; Recenter buffer after jumping.
-  (add-hook
-   'imenu-after-jump-hook
-   (lambda () (recenter (max scroll-margin (/ (window-height) 3)))))
-
-  (setq-default imenu-auto-rescan t)
-  (setq-default imenu-auto-rescan-maxout (* 1024 1024))
-  (setq-default imenu--rescan-item '("" . -99)))
+;;; Configure how to install packages
+(require 'package)
 
-;;; package
-(with-eval-after-load 'package
-  (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
-  (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))
-  (add-to-list 'package-archives '("elpa" . "https://elpa.nongnu.org/nongnu/"))
-  (add-to-list 'package-archives '("gnu-devel" . "https://elpa.gnu.org/devel/") t))
+(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
+(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))
+(add-to-list 'package-archives '("elpa" . "https://elpa.nongnu.org/nongnu/"))
 
-(require 'package)
 (package-initialize)
 
 ;; Auto-install use-package.
@@ -75,803 +31,38 @@
 (eval-when-compile
   (require 'use-package))
 
-(setq debug-on-error init-file-debug)
-(setq use-package-always-defer nil)
-(setq use-package-always-ensure nil)
-(setq use-package-compute-statistics nil)
-(setq use-package-expand-minimally (not init-file-debug))
-(setq use-package-verbose init-file-debug)
-
-(eval-and-compile
-  (defsubst emacs-path (path)
-    (expand-file-name path user-emacs-directory))
-
-  (setq package-enable-at-startup nil
-	load-path
-	(append (list (emacs-path "use-package"))
-		(delete-dups load-path)
-		(list (emacs-path "lisp")))))
-
-(use-package diminish :ensure t)
-
-(defconst user-data-directory
-  (emacs-path "data"))
-
-(defun user-data (dir)
-  "Concat DIR under the user's directory."
-  (expand-file-name dir user-data-directory))
-
-(defvar saved-window-configuration nil)
-
-(defun push-window-configuration ()
-  (interactive)
-  (push (current-window-configuration) saved-window-configuration))
-
-(defun pop-window-configuration ()
-  (interactive)
-  (let ((config (pop saved-window-configuration)))
-    (if config
-        (set-window-configuration config)
-      (if (> (length (window-list)) 1)
-          (delete-window)
-        (bury-buffer)))))
-
-(defun my/rename-this-buffer-and-file ()
-  "Renames current buffer and file it is visiting."
-  (interactive)
-  (let ((name (buffer-name))
-        (filename (buffer-file-name))
-        (read-file-name-function 'read-file-name-default))
-    (if (not (and filename (file-exists-p filename)))
-        (error "Buffer '%s' is not visiting a file!" name)
-      (let ((new-name (read-file-name "New name: " filename)))
-        (cond ((get-buffer new-name)
-               (error "A buffer named '%s' already exists!" new-name))
-              (t
-               (rename-file filename new-name 1)
-               (rename-buffer new-name)
-               (set-visited-file-name new-name)
-               (set-buffer-modified-p nil)
-               (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))))
-
-(defun my/check-work-machine-p ()
-  "Return t if this is a work machine."
-  (string-match "HQ\\.*" (system-name)))
-
-(defun my/github-code-search ()
-  "Search code on github for a given language."
-  (interactive)
-  (let ((language (completing-read
-                   "Language: "
-                   '("Emacs Lisp" "Python"  "Go" "Nix")))
-        (code (read-string "Code: ")))
-    (browse-url
-     (concat "https://github.com/search?lang=" language
-             "&type=code&q=" code))))
-
-(defun my/work-code-search ()
-  "Search code on sourcegraph for a given language."
-  (interactive)
-  (let ((language (completing-read
-                   "Language: "
-                   '("Ruby" "Python"  "Go")))
-        (code (read-string "Code: ")))
-    (browse-url
-     (concat "https://sourcegraph.rbx.com/search?q=context:global+lang:" language
-             "+" code))))
-
-;;; display mode
-;; paren.el
-(show-paren-mode 1)
-(setq show-paren-delay 0)
-(setq show-paren-highlight-openparen t)
-(setq show-paren-when-point-inside-paren t)
-(setq show-paren-when-point-in-periphery t)
-
-(use-package abbrev
-  :diminish
-  :hook
-  ((text-mode prog-mode) . abbrev-mode)
-  :custom
-  (abbrev-file-name (emacs-path "abbrevs.el"))
-  ;; save abbrevs when files are saved
-  (save-abbrevs 'silently)
-  :config
-  (if (file-exists-p abbrev-file-name)
-      (quietly-read-abbrev-file)))
-
-(use-package autorevert
-  :custom
-  (auto-revert-use-notify nil)
-  :config
-  (global-auto-revert-mode t))
-
-(use-package bookmark
-  :defer t
-  :custom
-  (bookmark-default-file (user-data "bookmarks")))
-
-(use-package compile
-  :bind (:map compilation-mode-map
-              ("z" . delete-window))
-  :custom
-  (compilation-always-kill t)
-  ;; Don't freeze when process reads from stdin
-  (compilation-disable-input t)
-  (compilation-ask-about-save nil)
-  (compilation-context-lines 10)
-  (compilation-scroll-output 'first-error)
-  (compilation-skip-threshold 2)
-  (compilation-window-height 100))
-
-(use-package consult
-  :ensure t
-  :bind (("C-c m"   . consult-mode-command)
-	 ("M-g o"   . consult-org-heading)
-	 ("C-x b"   . consult-buffer)
-	 ("C-x r b" . consult-bookmark)
-	 ("C-x p b" . consult-project-buffer)
-	 ("C-c i"   . consult-imenu)
-	 ("M-g e"   . consult-compile-error)
-	 ("M-g g"   . consult-goto-line)
-	 ("M-g M-g" . consult-goto-line)
-	 ("M-g m"   . consult-mark)
-	 ("M-g k"   . consult-global-mark)))
-
-(use-package corfu
-  :ensure t
-  :demand t
-  :bind (("M-/" . completion-at-point)
-	 :map corfu-map
-	 ("C-n"      . corfu-next)
-	 ("C-p"      . corfu-previous)
-	 ("<return>" . corfu-insert)
-	 ("M-d"      . corfu-info-documentation)
-	 ("M-l"      . corfu-info-location)
-	 ("M-."      . corfu-move-to-minibuffer))
-  :custom
-  ;; Works with `indent-for-tab-command'. Make sure tab doesn't indent when you
-  ;; want to perform completion
-  (tab-always-indent 'complete)
-  (completion-cycle-threshold t)      ; Always show candidates in menu
-
-  (corfu-auto t)
-  (corfu-auto-prefix 2)
-  (corfu-auto-delay 0.25)
-
-  (corfu-min-width 80)
-  (corfu-max-width corfu-min-width)     ; Always have the same width
-  (corfu-cycle t)
-
-  ;; `nil' means to ignore `corfu-separator' behavior, that is, use the older
-  ;; `corfu-quit-at-boundary' = nil behavior. Set this to separator if using
-  ;; `corfu-auto' = `t' workflow (in that case, make sure you also set up
-  ;; `corfu-separator' and a keybind for `corfu-insert-separator', which my
-  ;; configuration already has pre-prepared). Necessary for manual corfu usage with
-  ;; orderless, otherwise first component is ignored, unless `corfu-separator'
-  ;; is inserted.
-  (corfu-quit-at-boundary nil)
-  (corfu-separator ?\s)            ; Use space
-  (corfu-quit-no-match 'separator) ; Don't quit if there is `corfu-separator' inserted
-  (corfu-preview-current 'insert)  ; Preview first candidate. Insert on input if only one
-  (corfu-preselect-first t)        ; Preselect first candidate?
-
-  ;; Other
-  (corfu-echo-documentation nil)        ; Already use corfu-popupinfo
-
-  :init
-  ;; see https://github.com/minad/corfu#completing-in-the-eshell-or-shell
-  (add-hook 'eshell-mode-hook
-            (lambda ()
-              (setq-local corfu-auto nil)
-              (corfu-mode)))
-  :config
-  (global-corfu-mode))
-
-(use-package corfu-popupinfo
-  :after corfu
-  :hook (corfu-mode . corfu-popupinfo-mode)
-  :bind (:map corfu-map
-              ("M-n" . corfu-popupinfo-scroll-up)
-              ("M-p" . corfu-popupinfo-scroll-down)
-              ([remap corfu-show-documentation] . corfu-popupinfo-toggle))
-  :custom
-  (corfu-popupinfo-delay 0.5)
-  (corfu-popupinfo-max-width 70)
-  (corfu-popupinfo-max-height 20)
-  ;; Also here to be extra-safe that this is set when `corfu-popupinfo' is
-  ;; loaded. I do not want documentation shown in both the echo area and in
-  ;; the `corfu-popupinfo' popup.
-  (corfu-echo-documentation nil))
-
-(use-package cape
-  :demand t
-  :ensure t
-  :bind (("C-c . p" . completion-at-point)
-	 ("C-c . h" . cape-history)
-	 ("C-c . f" . cape-file)
-	 ("C-c . a" . cape-abbrev)
-	 ("C-c . l" . cape-line)
-	 ("C-c . w" . cape-dict)
-	 ("C-c . r" . cape-rfc1345))
-  :init
-  ;; Add `completion-at-point-functions', used by `completion-at-point'.
-  (add-to-list 'completion-at-point-functions #'cape-file)
-  (add-to-list 'completion-at-point-functions #'cape-abbrev))
-
-  (use-package marginalia
-    :ensure t
-    ;; Either bind `marginalia-cycle' globally or only in the minibuffer
-    :bind (:map minibuffer-local-map
-         ("M-A" . marginalia-cycle))
-
-    :init
-    ;; Must be in the :init section of use-package such that the mode gets
-    ;; enabled right away. Note that this forces loading the package.
-    (marginalia-mode))
-
-  (use-package orderless
-    :demand t
-    :ensure t
-    :custom
-    (completion-styles '(orderless basic))
-    (completion-category-defaults nil))
-
-  (use-package vertico
-    :ensure t
-    :config
-    (vertico-mode))
-
-(use-package yasnippet
-  :ensure t
-  :defer t
-  :diminish
-  :hook ((prog-mode . yas-minor-mode))
-  :config
-  (yas-reload-all))
-
-(use-package dired
-  :diminish
-  :bind (:map dired-mode-map
-              ("j"     . dired)
-              ("z"     . pop-window-configuration)
-              ("^"     . dired-up-directory)
-              ("q"     . pop-window-configuration)
-              ("M-!"   . shell-command)
-              ("<tab>" . dired-next-window))
-  :custom
-  (dired-clean-up-buffers-too nil)
-  (dired-dwim-target t)
-  (dired-hide-details-hide-information-lines nil)
-  (dired-hide-details-hide-symlink-targets nil)
-  (dired-listing-switches "-lah")
-  (dired-no-confirm
-   '(byte-compile chgrp chmod chown copy hardlink symlink touch))
-  (dired-omit-mode nil t)
-  (dired-omit-size-limit 60000)
-  (dired-recursive-copies 'always)
-  (dired-recursive-deletes 'always)
-  :functions (dired-dwim-target-directory))
-
-  (use-package direnv
-    :ensure t
-    :custom
-    (direnv-always-show-summary nil)
-    :config
-    (direnv-mode))
-
-(use-package docker
-  :bind ("C-c d" . docker)
-  :diminish
-  :init
-  (use-package docker-image   :commands docker-images)
-  (use-package docker-volume  :commands docker-volumes)
-  (use-package docker-network :commands docker-containers)
-  (use-package docker-compose :commands docker-compose)
-
-  (use-package docker-container
-    :commands docker-containers
-    :custom
-    (docker-containers-shell-file-name "/bin/bash")
-    (docker-containers-show-all nil)))
-
-(use-package docker-compose-mode
-  :ensure t
-  :mode "docker-compose.*\.yml\\'")
-
-(use-package dockerfile-mode
-  :ensure t
-  :mode "Dockerfile[a-zA-Z.-]*\\'")
-
-  (use-package emacs
-    :bind* ("M-j" . join-line)
-
-    :custom-face
-    (cursor ((t (:background "hotpink"))))
-    ;; (highlight ((t (:background "blue4"))))
-    ;; (minibuffer-prompt ((t (:foreground "grey80"))))
-    ;; (mode-line-inactive ((t (:background "grey50"))))
-    (nobreak-space ((t nil)))
-
-    :custom
-
-    (create-lockfiles nil)                      ;; don't use a lock file
-    (confirm-kill-emacs #'yes-or-no-p)          ;; ask before killing emacs
-    (minibuffer-message-timeout 0.5)            ;; How long to display an echo-area message
-    (next-screen-context-lines 5)               ;; scroll 5 lines at a time
-    (require-final-newline t)                   ;; ensure newline exists at the end of the file
-    (ring-bell-function 'ignore)                ;; really no bell
-    (tab-always-indent 'complete)               ;; when using TAB, always indent
-    (visible-bell nil)                          ;; no bell
-    (column-number-mode t)                      ;; show column number in the mode line
-    (electric-pair-mode 1)                      ;; matches parens and brackets
-    (indent-tabs-mode nil)                      ;; turn off tab indentation
-    (cursor-type 'box)                          ;; cursor is a horizontal bar
-    (delete-by-moving-to-trash t)               ;; delete files by moving them to the trash
-    (initial-scratch-message "")                ;; empty scratch buffer
-
-    ;; bytecomp.el
-    (byte-compile-verbose nil)
-
-    ;; prog-mode.el
-    (prettify-symbols-unprettify-at-point 'right-edge)
-
-    ;; startup.el
-    (initial-buffer-choice t)
-    (initial-major-mode 'fundamental-mode)
-    (initial-scratch-message "")
-
-    (user-full-name "Franck Cuny")
-    (user-mail-address "franck@fcuny.net")
-    (add-log-mailing-address "franck@fcuny.net")
-
-    (history-length 200)
-    (history-delete-duplicates t)
-    (completion-ignored-extensions
-     '(".class"
-       ".cp"
-       ".elc"
-       ".fmt"
-       ".git/"
-       ".pyc"
-       ".so"
-       "~"))
-
-    ;; paragraphs.el
-    (sentence-end-double-space nil)
-
-    ;; switch to view-mode whenever you are in a read-only buffer (e.g.
-    ;; switched to it using C-x C-q).
-    (view-read-only t)
-
-    ;; window.el
-    (switch-to-buffer-preserve-window-point t)
-
-    ;; warnings.el
-    (warning-minimum-log-level :error)
-
-    ;; frame.el
-    (window-divider-default-bottom-width 1)
-    (window-divider-default-places 'bottom-only)
-
-    :config
-    (add-hook 'after-save-hook
-              #'executable-make-buffer-file-executable-if-script-p))
-
-(use-package eshell
-  :commands (eshell eshell-command)
-  :custom
-  (eshell-directory-name (emacs-path "eshell"))
-  (eshell-hist-ignoredups t)
-  (eshell-history-size 50000)
-  (eshell-ls-dired-initial-args '("-h"))
-  (eshell-ls-exclude-regexp "~\\'")
-  (eshell-ls-initial-args "-h")
-  (eshell-modules-list
-   '(eshell-alias
-     eshell-basic
-     eshell-cmpl
-     eshell-dirs
-     eshell-glob
-     eshell-hist
-     eshell-ls
-     eshell-pred
-     eshell-prompt
-     eshell-rebind
-     eshell-script
-     eshell-term
-     eshell-unix
-     eshell-xtra))
-  (eshell-prompt-function
-   (lambda nil
-     (concat (abbreviate-file-name (eshell/pwd))
-             (if (= (user-uid) 0)
-                 " # " " $ "))))
-  (eshell-save-history-on-exit t)
-  (eshell-stringify-t nil)
-  (eshell-term-name "ansi")
-
-  :preface
-  (defun eshell-initialize ()
-    (add-hook 'eshell-expand-input-functions #'eshell-spawn-external-command)
-
-  :init
-  (add-hook 'eshell-first-time-mode-hook #'eshell-initialize)))
-
-(use-package flymake
-  :bind (("C-c ! n" . flymake-goto-next-error)
-         ("C-c ! p" . flymake-goto-next-error))
-  :custom
-  (flymake-start-on-save-buffer t)
-  (flymake-fringe-indicator-position 'left-fringe)
-  (flymake-suppress-zero-counters t)
-  (flymake-proc-compilation-prevents-syntax-check t)
-  (elisp-flymake-byte-compile-load-path load-path))
-
-;; use various monaspace fonts
-;; https://monaspace.githubnext.com
-(set-face-attribute 'default nil
-                    :font "Monaspace Neon"
-                    :height 150)
-
-(set-face-attribute 'fixed-pitch nil
-                    :font "Monaspace Neon"
-                    :height 150)
-
-(set-face-attribute 'variable-pitch nil
-                    :font "Monaspace Radon"
-                    :height 150)
-
-(custom-set-faces
- '(font-lock-comment-face ((t (:font "Monaspace Radon" :italic t :height 1.0)))))
-
-(use-package fringe
-  :config
-  ;;; no fringe on the right side
-  (set-fringe-mode '(8 . 0)))
-
-  (use-package git-link
-    :defines git-link-remote-alist
-    :ensure t
-    :bind ("C-c Y" . git-link)
-    :commands (git-link git-link-commit git-link-homepage)
-
-    :custom
-    (git-link-open-in-browser t)
-
-    :preface
-    (defun git-link-fcuny-net (hostname dirname filename branch commit start end)
-      (format "http://git.fcuny.net/%s/tree/%s?id=%s#n%s"
-              (replace-regexp-in-string "^r/\\(.*\\)" "\\1.git" dirname)
-              filename
-              commit
-              start))
-
-    (defun git-link-commit-fcuny-net (hostname dirname commit)
-      (format "http://git.fcuny.net/%s/commit/?id=%s"
-              (replace-regexp-in-string "^r/\\(.*\\)" "\\1.git" dirname)
-              commit))
-
-    :config
-    (add-to-list 'git-link-remote-alist '("git\\.fcuny\\.net" git-link-fcuny-net))
-    (add-to-list 'git-link-commit-remote-alist '("git\\.fcuny\\.net" git-link-commit-fcuny-net))
-
-    ;; sets up roblox git enterprise as a git-link handler
-    (add-to-list 'git-link-remote-alist '("github\\.rblx\\.com" git-link-github))
-    (add-to-list 'git-link-commit-remote-alist '("github\\.rblx\\.com" git-link-commit-github)))
-
-(use-package ibuffer
-  :bind ("C-x C-b" . ibuffer)
-  :custom
-  (ibuffer-default-display-maybe-show-predicates t)
-  (ibuffer-expert t)
-  (ibuffer-formats
-   '((mark modified read-only " "
-           (name 16 -1)
-           " "
-           (size 6 -1 :right)
-           " "
-           (mode 16 16)
-           " " filename)
-     (mark " "
-           (name 16 -1)
-           " " filename)))
-  (ibuffer-maybe-show-regexps nil)
-  (ibuffer-saved-filter-groups
-   '(("default"
-      ("Magit"
-       (or
-        (mode . magit-status-mode)
-        (mode . magit-log-mode)
-        (name . "\\*magit")
-        (name . "magit-")
-        (name . "git-monitor")))
-      ("Commands"
-       (or
-        (mode . shell-mode)
-        (mode . eshell-mode)
-        (mode . term-mode)
-        (mode . compilation-mode)))
-      ("Rust"
-       (or
-        (mode . rust-mode)
-        (mode . cargo-mode)
-        (name . "\\*Cargo")
-        (name . "^\\*rls\\(::stderr\\)?\\*")
-        (name . "eglot")))
-      ("Nix"
-       (mode . nix-mode))
-      ("Lisp"
-       (mode . emacs-lisp-mode))
-      ("Dired"
-       (mode . dired-mode))
-      ("Org"
-       (or
-        (name . "^\\*Calendar\\*$")
-        (name . "^\\*Org Agenda")
-        (name . "^ \\*Agenda")
-        (name . "^diary$")
-        (mode . org-mode)))
-      ("Emacs"
-       (or
-        (name . "^\\*scratch\\*$")
-        (name . "^\\*Messages\\*$")
-        (name . "^\\*\\(Customize\\|Help\\)")
-        (name . "\\*\\(Echo\\|Minibuf\\)"))))))
-  (ibuffer-show-empty-filter-groups nil)
-  (ibuffer-shrink-to-minimum-size t t)
-  (ibuffer-use-other-window t)
-  :init
-  (add-hook 'ibuffer-mode-hook
-            #'(lambda ()
-                (ibuffer-switch-to-saved-filter-groups "default"))))
-
-(use-package indent
-  :commands indent-according-to-mode
-  :custom
-  (tab-always-indent 'complete))
-
-  (use-package ispell
-    :custom
-    (ispell-program-name (executable-find "aspell"))
-    (ispell-dictionary "en_US")
-    (ispell-extra-args '("--camel-case")))
-
-  (use-package jq-mode
-    :ensure t
-    :mode "\\.jq\\'")
-
-(use-package eglot
-  :ensure t
-  :after yasnippet
-  :bind (:map eglot-mode-map
-              ("C-c l a" . eglot-code-actions)
-              ("C-c l r" . eglot-rename))
-  :config
-  (setq-default eglot-workspace-configuration
-                '((gopls
-		   (usePlaceholders . t)
-		   (staticcheck . t)
-		   (completeUnimported . t))))
-
-  ;; uses https://github.com/oxalica/nil for the LSP server instead of rnix
-  (add-to-list 'eglot-server-programs '(nix-mode . ("nixd"))))
-
-(use-package tree-sitter
-  :ensure t
-  :config
-  (global-tree-sitter-mode))
-
-(use-package tree-sitter-langs
-  :after tree-sitter
-  :ensure t)
-
-(use-package emacs-lisp-mode
-  :bind (:map emacs-lisp-mode-map
-              ("C-c C-r" . eval-region)
-              ("C-c C-d" . eval-defun)
-              ("C-c C-b" . eval-buffer))
-  :hook ((emacs-lisp-mode . flymake-mode)))
-
-(use-package eldoc
-  :diminish
-  :hook ((c-mode-common emacs-lisp-mode) . eldoc-mode)
-  :custom
-  (eldoc-idle-delay 1)
-  (eldoc-documentation-strategy #'eldoc-documentation-default)
-  (eldoc-echo-area-use-multiline-p 3)
-  (eldoc-echo-area-prefer-doc-buffer 'maybe)
-  (eldoc-echo-area-display-truncation-message nil))
-
-  (use-package hcl-mode
-    :ensure t
-    :mode "\.nomad\\'")
-
-(use-package json-mode
-  :mode "\\.json\\'")
-
-(use-package json-reformat
-  :ensure t
-  :after json-mode)
-
-(use-package go-mode
-  :ensure t
-  :defer t
-  :hook ((go-mode . tree-sitter-hl-mode)
-         (go-mode . eglot-ensure)
-         (go-mode . (lambda () (setq tab-width 4)))
-         (go-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t))))
-  :bind (:map go-mode-map
-              ("C-c C-c" . compile)))
-
-(use-package gotest
-  :ensure t
-  :after go-mode
-  :custom
-  (go-test-verbose t))
-
-  (use-package nix-mode
-    :ensure t
-    :hook ((nix-mode . eglot-ensure)
-           (nix-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t))))
-    :custom
-    (nix-indent-function 'nix-indent-line))
-
-  (use-package protobuf-mode
-    :ensure t
-    :mode "\\.proto\\'")
-
-(use-package python-mode
-  :hook ((python-mode . tree-sitter-hl-mode)
-         (python-mode . eglot-ensure))
-  :interpreter "python"
-  :bind (:map python-mode-map
-              ("C-c c")
-              ("C-c C-z" . python-shell)))
-
-(use-package blacken
-  :ensure t
-  :hook (python-mode . blacken-mode))
-
-  (use-package py-isort
-    :ensure t
-    :commands (py-isort-buffer py-isort-region))
-
-  (use-package ruby-mode
-    :mode "\\.rb\\'"
-    :interpreter "ruby"
-    :bind (:map ruby-mode-map
-                ("<return>" . my-ruby-smart-return))
-    :preface
-    (defun my-ruby-smart-return ()
-      (interactive)
-      (when (memq (char-after) '(?\| ?\" ?\'))
-        (forward-char))
-      (call-interactively 'newline-and-indent)))
-
-(use-package sh-script
-  :defer t
-  :preface
-  (defvar sh-script-initialized nil)
-
-  (defun initialize-sh-script ()
-    (unless sh-script-initialized
-      (setq sh-script-initialized t)
-      (info-lookup-add-help :mode 'shell-script-mode
-                            :regexp ".*"
-                            :doc-spec '(("(bash)Index")))))
-  :init
-  (add-hook 'shell-mode-hook #'initialize-sh-script))
-
-(use-package terraform-mode
-  :ensure t
-  :mode "\.tf\\'")
-
-(use-package toml-mode
-  :defer t
-  :ensure t)
-
-(use-package yaml-mode
-  :ensure t
-  :mode "\\.ya?ml\\'")
-
-(when (memq window-system '(mac ns))
-  (add-to-list 'default-frame-alist '(fullscreen . maximized))
-  (add-to-list 'default-frame-alist '(ns-appearance . nil))
-  (add-to-list 'default-frame-alist '(ns-transparent-titlebar . nil))
-  (when (boundp 'ns-use-native-fullscreen)
-    (setq ns-use-native-fullscreen nil))
-  (when (boundp 'mac-allow-anti-aliasing)
-    (setq mac-allow-anti-aliasing t)))
-
-(use-package exec-path-from-shell
-  :ensure t
-  :demand t
-  :if (memq window-system '(mac ns))
-  :config
-  (exec-path-from-shell-initialize))
-
-  (use-package magit
-    :defer t
-    :ensure t
-    :bind (("C-x g" . magit-status)
-           ("C-x G" . magit-status-with-prefix))
-    :custom
-    (magit-diff-options nil)
-    (magit-diff-refine-hunk t)
-    (magit-fetch-arguments nil)
-    (magit-log-section-commit-count 10)
-    (magit-pre-refresh-hook nil)
-    (magit-process-popup-time 15)
-    (magit-clone-default-directory "~/workspace/")
-    (magit-section-initial-visibility-alist '((untracked . hide)))
-    :hook (magit-mode . hl-line-mode)
-    :config
-    (use-package magit-commit
-      :defer t
-      :config
-      (use-package git-commit
-        :custom
-        (git-commit-major-mode 'markdown-mode)
-        (git-commit-setup-hook
-         '(git-commit-save-message
-           git-commit-turn-on-auto-fill
-           git-commit-turn-on-flyspell
-           bug-reference-mode))))
-
-    (use-package magit-status
-      :defer t
-      :config
-      (dolist (func '(magit-insert-unpushed-to-upstream-or-recent
-                      magit-insert-unpulled-from-pushremote
-                      magit-insert-unpulled-from-upstream
-                      ))
-        (remove-hook 'magit-status-sections-hook func))
-
-      (dolist (func '(magit-insert-diff-filter-header
-                      magit-insert-tags-header))
-        (remove-hook 'magit-status-headers-hook func))))
-
-(use-package markdown-mode
-  :mode (("\\`README\\.md\\'" . gfm-mode)
-         ("\\.md\\'"          . markdown-mode)
-         ("\\.markdown\\'"    . markdown-mode))
-  :custom
-  (markdown-command "pandoc -f markdown_github+smart")
-  (markdown-command-needs-filename t)
-  (markdown-enable-math t)
-  (markdown-open-command "marked")
-  :init
-  (setq markdown-command "multimarkdown"))
-
-  (use-package markdown-preview-mode
-    :ensure t
-    :after markdown-mode
-    :config
-    (setq markdown-preview-stylesheets
-	  (list (concat "https://github.com/dmarcotte/github-markdown-preview/"
-			"blob/master/data/css/github.css"))))
-
-(use-package midnight
-  :demand t
-  :bind ("C-c z" . clean-buffer-list)
-  :custom
-  (midnight-delay 18000)
-  (clean-buffer-list-kill-never-buffer-names
-   '("*scratch*"
-     "*Messages*"
-     "*server*"
-     "*Group*"
-     "*Org Agenda*"
-     "todo.org"))
-  (clean-buffer-list-kill-never-regexps
-   '("^ \\*Minibuf-.*\\*$"
-     "^\\*Summary"
-     "^\\*Article" "^#"))
-  (clean-buffer-list-kill-regexps '(".*"))
-  :config
-  (midnight-mode t))
-
+;;; Custom configurations
+;; Load custom code under the "lisp" and "config" directories.
+(add-to-list 'load-path (expand-file-name "config" user-emacs-directory))
+(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
+
+(require 'init-ui)
+(require 'init-modeline)
+(require 'init-theme)
+(require 'init-session)
+
+(require 'init-osx)
+
+(require 'init-buffer)
+(require 'init-dired)
+(require 'init-file)
+(require 'init-time)
+(require 'init-project)
+(require 'init-snippets)
+(require 'init-completion)
+(require 'init-whitespace)
+(require 'init-rg)
+
+(require 'init-keys)
+(require 'init-imenu)
+(require 'init-git)
+
+(require 'init-programming)
+(require 'init-writing)
+(require 'init-org)
+(require 'init-eshell)
+
+;;; Custom modules
 (use-package my-cheeseboard)
 
 (use-package my-uptime
@@ -882,270 +73,6 @@
                                        (slot . 0)
                                        (window-width . 0.35))))
 
-  (use-package org
-    :hook
-    (org-mode . turn-on-flyspell)
-    (org-mode . visual-line-mode)
-    (org-mode . org-indent-mode)
-    :custom
-    ;;; general settings
-    (org-startup-folded t)
-    (org-startup-indented t)
-    (org-hide-emphasis-markers t)
-    (org-hide-leading-stars t)
-    (org-pretty-entities t)
-    (org-return-follows-link t)
-    (org-startup-with-inline-images t)
-    (org-export-backends '(html md))
-    (org-imenu-depth 4)
-    (org-insert-heading-respect-content t)
-    (org-outline-path-complete-in-steps nil)
-    (org-src-fontify-natively t)
-    (org-src-preserve-indentation t)
-    (org-src-tab-acts-natively t)
-    (org-src-window-setup 'current-window)
-    (org-yank-adjusted-subtrees t)
-    (org-structure-template-alist
-        '(("s" . "src")
-          ("E" . "src emacs-lisp")
-          ("p" . "src python")
-          ("e" . "example")
-          ("q" . "quote")
-          ("V" . "verbatim")))
-    :config
-    (font-lock-add-keywords 'org-mode
-                            '(("^ *\\(-\\) "
-                               (0 (ignore (compose-region (match-beginning 1) (match-end 1) "•")))))))
-
-(use-package org-bullets
-  :ensure t
-  :hook (org-mode . org-bullets-mode))
-
-(use-package org-auto-tangle
-  :ensure t
-  :hook (org-mode . org-auto-tangle-mode))
-
-(use-package org-babel
-  :no-require t
-  :after (org)
-  :config
-  (org-babel-do-load-languages
-   'org-babel-load-languages
-   '((python     . t)
-     (emacs-lisp . t)
-     (calc       . t)
-     (shell      . t)
-     (sql        . t)
-     (dot        . t)))
-
-  (remove-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory)
-
-  (advice-add 'org-babel-edit-prep:emacs-lisp :after
-              #'(lambda (_info) (run-hooks 'emacs-lisp-mode-hook))))
-
-(use-package ox-gfm
-  :ensure t
-  :after org)
-
-(use-package ox-md
-  :after org)
-
-(use-package ox-pandoc
-  :ensure t
-  :after org
-  :preface
-  (defun markdown-to-org-region (start end)
-    "Convert region from markdown to org, replacing selection"
-    (interactive "r")
-    (shell-command-on-region start end "pandoc -f markdown -t org" t t)))
-
-  (use-package project
-  :ensure nil
-  :custom
-  (project-switch-commands
-   '((project-dired "Root" ?d)
-     (project-find-file "File" ?f)
-     (project-switch-to-buffer "Buffer" ?b)
-     (project-eshell "Shell" ?e)
-     (magit-project-status "Git" ?g)))
-  :init
-  (setq-default project-list-file (user-data "projects.eld")))
-
-(use-package recentf
-  :demand t
-  :commands (recentf-mode
-             recentf-add-file
-             recentf-apply-filename-handlers)
-  :custom
-  (recentf-auto-cleanup 60)
-  (recentf-exclude
-   '("~\\'" "\\`out\\'" "\\.log\\'" "^/[^/]*:" "\\.el\\.gz\\'" "\\.gz\\'"))
-  (recentf-max-saved-items 2000)
-  (recentf-save-file (user-data "recentf"))
-  :preface
-  :config
-  (recentf-mode 1))
-
-(use-package restclient
-  :ensure t
-  :mode ("\\.rest\\'" . restclient-mode))
-
-  (use-package rg
-    :ensure t
-    :custom ((rg-group-result t)
-             (rg-show-columns t)
-             (rg-align-line-number-field-length 3)
-             (rg-align-column-number-field-length 3)
-             (rg-align-line-column-separator "#")
-             (rg-align-position-content-separator "|")
-             (rg-hide-command nil)
-             (rg-align-position-numbers t)
-             (rg-command-line-flags '("--follow"))))
-
-(use-package savehist
-  :unless noninteractive
-  :custom
-  (savehist-additional-variables
-   '(file-name-history
-     kmacro-ring
-     compile-history
-     compile-command))
-  (savehist-autosave-interval 60)
-  (savehist-file (user-data "history"))
-  (savehist-ignored-variables
-   '(load-history
-     flyspell-auto-correct-ring
-     org-roam-node-history
-     magit-revision-history
-     org-read-date-history
-     query-replace-history
-     yes-or-no-p-history
-     kill-ring))
-  (savehist-mode t)
-  :config
-  (savehist-mode 1))
-
-(use-package saveplace
-  :unless noninteractive
-  :custom
-  (save-place-file (user-data "places"))
-  :config
-  (save-place-mode 1))
-
-(use-package modus-themes
-  :ensure t
-  :custom
-  ;; Syntax Highlighting
-  (modus-themes-bold-constructs t)
-  (modus-operandi-palette-overrides '((comment red-faint)
-                                      (string "#101010")
-                                      (bg-main "#FFFCF6")))
-
-  (modus-themes-italic-constructs t)
-
-  ;; Use mixed fonts
-  (modus-themes-mixed-fonts t)
-  (modus-themes-variable-pitch-ui t)
-
-  ;; Enhance minibuffer completions
-  (modus-themes-prompts '(italic bold))
-  (modus-themes-completions '((matches . (extrabold))
-                              (selection . (semibold italic text-also))))
-
-  ;; Org Mode
-  ;;; Make headings in org files more distinct
-  (modus-themes-headings '((t . (background bold rainbow 1))))
-  ;;; Tint the background of code blocks in org files
-  (modus-themes-org-blocks 'tinted-background)
-  ;;; Make tags less colorful and tables look the same as
-  ;;; the default foreground.
-  (prose-done cyan-cooler)
-  (prose-tag fg-dim)
-  (prose-table fg-main)
-
-  ;; Make the fringe more intense
-  (modus-themes-common-palette-overrides '((fringe bg-active)))
-
-  :config
-  (load-theme 'modus-operandi t))
-
-(use-package time
-  :custom
-  (display-time-interval 60)
-  (display-time-mode t)
-  (display-time-24hr-format t)
-  (display-time-day-and-date t)
-  (display-time-default-load-average nil)
-  (world-clock-list t)
-  (world-clock-timer-enable t)
-  (world-clock-timer-second 60)
-  ;; UTC      => 02:42 +0000  Wednesday 20 April
-  ;; Berkeley => 19:42 -0700  Tuesday 19 April
-  (world-clock-time-format "%R %z  %A %d %B")
-  (zoneinfo-style-world-list '(("UTC" "UTC")
-                               ("America/Los_Angeles" "Berkeley")
-                               ("America/Denver" "Mountain Time")
-                               ("America/Chicago" "Central Time")
-                               ("America/New_York" "New York")
-                               ("Europe/London" "London")
-                               ("Europe/Paris" "Paris")))
-  :init
-  (add-to-list 'display-buffer-alist '("\\*wclock\\*"
-                                       (display-buffer-in-side-window)
-                                       (side . left)
-                                       (slot . 0)
-                                       (window-width . 0.35))))
-
-  (use-package tramp
-    :defer t
-    :custom
-    (tramp-default-method "ssh")
-    (tramp-auto-save-directory "~/.cache/emacs/backups")
-    (tramp-ssh-controlmaster-options "-o ControlMaster=auto -o ControlPath='tramp.%%C'")
-    :config
-    ;; Setting this with `:custom' does not take effect.
-    (setq tramp-persistency-file-name (user-data "tramp")))
-
-(use-package transient
-  :defer t
-  :custom
-  (transient-history-file (user-data "transient/history.el"))
-  (transient-values-file (user-data "transient/values.el")))
-
-(use-package vc
-  :defer t
-  :custom
-  (vc-command-messages t)
-  (vc-follow-symlinks t))
-
-(use-package which-key
-  :demand t
-  :diminish
-  :ensure t
-  :config
-  (which-key-mode))
-
-(use-package whitespace
-  :diminish (global-whitespace-mode
-             whitespace-mode
-             whitespace-newline-mode)
-  :commands (whitespace-buffer
-             whitespace-cleanup
-             whitespace-mode
-             whitespace-turn-off)
-  :init
-  (dolist (hook '(prog-mode-hook text-mode-hook))
-    (add-hook hook #'whitespace-mode))
-  :custom
-  (whitespace-auto-cleanup t t)
-  (whitespace-rescan-timer-time nil t)
-  (whitespace-silent t t)
-  (whitespace-style '(face trailing space-before-tab))
-  :defines
-  (whitespace-auto-cleanup
-   whitespace-rescan-timer-time
-   whitespace-silent))
-
 ;;; Custom Variables
 (setq custom-file (user-data "customizations.el"))
 (load custom-file 'noerror)
diff --git a/init.org b/init.org
deleted file mode 100644
index 34fbae5..0000000
--- a/init.org
+++ /dev/null
@@ -1,1607 +0,0 @@
-#+TITLE: my Emacs configuration
-#+AUTHOR: Franck Cuny
-#+PROPERTY: header-args :results silent :tangle ~/.config/emacs/init.el
-#+STARTUP: overview indent
-#+AUTO_TANGLE: t
-
-To use this file, run =org-tangle= (or =C-c C-v C-t=).
-
-To exclude specific source blocks from being tangled add =:tangle no= to the header.
-
-* TODO set the mode when tangling the files
-When version 9.7 of org-mode is released, I need to add the following property to ~header-args~:
-- ~tangle-mode o444~ (see [[https://github.com/emacs-straight/org-mode/blob/f03b839530d86269bd23baef2965a316a4172895/etc/ORG-NEWS#L1307][this]] for more details)
-
-* Startup
-** early initialization
-:PROPERTIES:
-:header-args: :results silent :tangle ~/.config/emacs/early-init.el
-:END:
-
-Using an =early-init.el= file can speedup loading emacs. This is only available after emacs version 27.
-
-#+begin_src emacs-lisp :lexical t
-;;; early-init.el --- Early initialization -*- lexical-binding: t -*-
-
-;;; Commentary:
-
-;;; Code:
-
-;; disable GUI elements
-(scroll-bar-mode -1)      ; hide the scroll bar
-(tool-bar-mode -1)        ; hide the tool bar
-(menu-bar-mode -1)        ; hide the menu
-(blink-cursor-mode -1)    ; don't blink the cursor
-
-(setq make-pointer-invisible t)  ;; hide cursor while typing
-(setq use-dialog-box nil)        ;; do not show GUI dialogs
-(setq inhibit-startup-screen t)  ;; hide the startup screen
-
-;; don't report warnings and errors related to native compilation
-(setq native-comp-async-report-warnings-errors nil)
-
-;; increase font size
-(set-face-attribute 'default nil :height 130)
-
-;;; early-init.el ends here
-#+end_src
-
-** set headers
-
-#+begin_src emacs-lisp :epilogue (format-time-string ";; Last generated on %c")
-;;; init.el --- This is where all emacs start. -*- lexical-binding: t -*-
-
-;;; Commentary:
-
-;;; Code:
-#+end_src
-
-** garbage collection
-Set the garbage collection threshold.
-
-#+begin_src emacs-lisp
-(setq gc-cons-percentage 0.5
-      gc-cons-threshold (* 128 1024 1024))
-#+end_src
-
-** report time
-
-While I don't restart emacs that often, it's still useful to know how much time was spend loading the modules.
-
-#+begin_src emacs-lisp
-(defconst emacs-start-time (current-time))
-
-(defun report-time-since-load (&optional suffix)
-  (message "Loading init...done (%.3fs)%s"
-	   (float-time (time-subtract (current-time) emacs-start-time))
-	   suffix))
-
-(add-hook 'after-init-hook
-	  #'(lambda () (report-time-since-load " [after-init]"))
-	  t)
-#+end_src
-
-** generic configuration
-
-#+begin_src emacs-lisp
-(fset 'yes-or-no-p 'y-or-n-p)          ; replace yes/no prompts with y/n
-
-;; set utf-8 as the default encoding
-(prefer-coding-system 'utf-8-unix)
-(setq locale-coding-system 'utf-8)
-(set-language-environment 'utf-8)
-(set-terminal-coding-system 'utf-8)
-(set-keyboard-coding-system 'utf-8)
-#+end_src
-
-** load =use-package=
-
-Add MELPA and NonGNU ELPA repositories.
-
-#+begin_src emacs-lisp
-(setq load-prefer-newer t)
-(setq init-file-debug t)
-
-(package-initialize)
-
-(setq package-archives (append
-                        package-archives
-                        '(("melpa" . "https://melpa.org/packages/")
-                          ("elpa" . "https://elpa.nongnu.org/nongnu/"))))
-#+end_src
-
-Then we load =use-package=.
-
-#+begin_src emacs-lisp
-(eval-and-compile
-  (defsubst emacs-path (path)
-    (expand-file-name path user-emacs-directory))
-
-  (setq package-enable-at-startup nil
-	load-path
-	(append (list (emacs-path "use-package"))
-		(delete-dups load-path)
-		(list (emacs-path "lisp")))))
-
-(require 'use-package)
-
-(setq use-package-verbose init-file-debug
-      use-package-expand-minimally (not init-file-debug)
-      use-package-compute-statistics nil
-      debug-on-error init-file-debug)
-#+end_src
-
-*** diminish
-
-Since =use-package= no longer requires =diminish= as a dependency (see [[https://github.com/jwiegley/use-package/blob/a6e856418d2ebd053b34e0ab2fda328abeba731c/NEWS.md?plain=1#LL103C3-L103C62][changelog]]), we need to require it before other packages.
-
-#+begin_src emacs-lisp
-(use-package diminish :ensure t)
-#+end_src
-
-** define data environment
-
-#+begin_src emacs-lisp
-(defconst user-data-directory
-  (emacs-path "data"))
-
-(defun user-data (dir)
-  (expand-file-name dir user-data-directory))
-
-(setq custom-file (user-data "customizations.el"))
-(load custom-file 'noerror)
-#+end_src
-
-* Helper functions
-
-** Push and pop window configurations
-
-#+begin_src emacs-lisp
-(defvar saved-window-configuration nil)
-
-(defun push-window-configuration ()
-  (interactive)
-  (push (current-window-configuration) saved-window-configuration))
-
-(defun pop-window-configuration ()
-  (interactive)
-  (let ((config (pop saved-window-configuration)))
-    (if config
-        (set-window-configuration config)
-      (if (> (length (window-list)) 1)
-          (delete-window)
-        (bury-buffer)))))
-#+end_src
-
-** Rename the current buffer
-
-#+begin_src emacs-lisp
-(defun my/rename-this-buffer-and-file ()
-  "Renames current buffer and file it is visiting."
-  (interactive)
-  (let ((name (buffer-name))
-        (filename (buffer-file-name))
-        (read-file-name-function 'read-file-name-default))
-    (if (not (and filename (file-exists-p filename)))
-        (error "Buffer '%s' is not visiting a file!" name)
-      (let ((new-name (read-file-name "New name: " filename)))
-        (cond ((get-buffer new-name)
-               (error "A buffer named '%s' already exists!" new-name))
-              (t
-               (rename-file filename new-name 1)
-               (rename-buffer new-name)
-               (set-visited-file-name new-name)
-               (set-buffer-modified-p nil)
-               (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))))
-#+end_src
-
-** Is this my work issued machine
-
-#+begin_src emacs-lisp
-(defun my/check-work-machine-p ()
-  "Return t if this is a work machine."
-  (string-match "HQ\\.*" (system-name)))
-#+end_src
-
-** GitHub's code search
-
-#+begin_src emacs-lisp
-(defun my/github-code-search ()
-  "Search code on github for a given language."
-  (interactive)
-  (let ((language (completing-read
-                   "Language: "
-                   '("Emacs Lisp" "Python"  "Go" "Nix")))
-        (code (read-string "Code: ")))
-    (browse-url
-     (concat "https://github.com/search?lang=" language
-             "&type=code&q=" code))))
-#+end_src
-
-** Search work's repositories
-
-#+begin_src emacs-lisp
-(defun my/work-code-search ()
-  "Search code on sourcegraph for a given language."
-  (interactive)
-  (let ((language (completing-read
-                   "Language: "
-                   '("Ruby" "Python"  "Go")))
-        (code (read-string "Code: ")))
-    (browse-url
-     (concat "https://sourcegraph.rbx.com/search?q=context:global+lang:" language
-             "+" code))))
-#+end_src
-
-* Packages
-** abbrev
-
-If you want 'btw' to expand to 'by the way', type 'btw' followed by =C-x a i g=. The =g= is flow global, and you can define abbreviations per mode.
-
-| keys      | action                                           |
-|-----------+--------------------------------------------------|
-| =C-x a i g= | add a new abbreviation for all modes             |
-| =C-x a i l= | add a new abbreviation local to the current mode |
-
-#+begin_src emacs-lisp
-(use-package abbrev
-  :diminish
-  :hook
-  ((text-mode prog-mode) . abbrev-mode)
-  :custom
-  (abbrev-file-name (emacs-path "abbrevs.el"))
-  ;; save abbrevs when files are saved
-  (save-abbrevs 'silently)
-  :config
-  (if (file-exists-p abbrev-file-name)
-      (quietly-read-abbrev-file)))
-#+end_src
-
-** autorevert
-
-Automatically revert buffers if the file has changed on disk.
-
-#+begin_src emacs-lisp
-(use-package autorevert
-  :custom
-  (auto-revert-use-notify nil)
-  :config
-  (global-auto-revert-mode t))
-#+end_src
-
-** bookmark
-
-| keys    | action                             |
-|---------+------------------------------------|
-| =C-x r m= | add a new bookmark                 |
-| =C-x r l= | list all the bookmarks in a buffer |
-| =C-x r b= | list the bookmarks with consul     |
-
-#+begin_src emacs-lisp
-(use-package bookmark
-  :defer t
-  :custom
-  (bookmark-default-file (user-data "bookmarks")))
-#+end_src
-
-** compile
-Start a compilation with =M-x compile=.
-
-#+begin_src emacs-lisp
-(use-package compile
-  :bind (:map compilation-mode-map
-              ("z" . delete-window))
-  :custom
-  (compilation-always-kill t)
-  ;; Don't freeze when process reads from stdin
-  (compilation-disable-input t)
-  (compilation-ask-about-save nil)
-  (compilation-context-lines 10)
-  (compilation-scroll-output 'first-error)
-  (compilation-skip-threshold 2)
-  (compilation-window-height 100))
-#+end_src
-
-** completions
-*** consult
-The =consult= package provides search and navigation commands based on Emacs completion function =completing-read=.
-
-#+begin_src emacs-lisp
-(use-package consult
-  :ensure t
-  :bind (("C-c m"   . consult-mode-command)
-	 ("M-g o"   . consult-org-heading)
-	 ("C-x b"   . consult-buffer)
-	 ("C-x r b" . consult-bookmark)
-	 ("C-x p b" . consult-project-buffer)
-	 ("C-c i"   . consult-imenu)
-	 ("M-g e"   . consult-compile-error)
-	 ("M-g g"   . consult-goto-line)
-	 ("M-g M-g" . consult-goto-line)
-	 ("M-g m"   . consult-mark)
-	 ("M-g k"   . consult-global-mark)))
-#+end_src
-
-*** corfu
-Corfu enhances in-buffer completion with a small completion popup.
-
-#+begin_src emacs-lisp
-(use-package corfu
-  :ensure t
-  :demand t
-  :bind (("M-/" . completion-at-point)
-	 :map corfu-map
-	 ("C-n"      . corfu-next)
-	 ("C-p"      . corfu-previous)
-	 ("<return>" . corfu-insert)
-	 ("M-d"      . corfu-info-documentation)
-	 ("M-l"      . corfu-info-location)
-	 ("M-."      . corfu-move-to-minibuffer))
-  :custom
-  ;; Works with `indent-for-tab-command'. Make sure tab doesn't indent when you
-  ;; want to perform completion
-  (tab-always-indent 'complete)
-  (completion-cycle-threshold t)      ; Always show candidates in menu
-
-  (corfu-auto t)
-  (corfu-auto-prefix 2)
-  (corfu-auto-delay 0.25)
-
-  (corfu-min-width 80)
-  (corfu-max-width corfu-min-width)     ; Always have the same width
-  (corfu-cycle t)
-
-  ;; `nil' means to ignore `corfu-separator' behavior, that is, use the older
-  ;; `corfu-quit-at-boundary' = nil behavior. Set this to separator if using
-  ;; `corfu-auto' = `t' workflow (in that case, make sure you also set up
-  ;; `corfu-separator' and a keybind for `corfu-insert-separator', which my
-  ;; configuration already has pre-prepared). Necessary for manual corfu usage with
-  ;; orderless, otherwise first component is ignored, unless `corfu-separator'
-  ;; is inserted.
-  (corfu-quit-at-boundary nil)
-  (corfu-separator ?\s)            ; Use space
-  (corfu-quit-no-match 'separator) ; Don't quit if there is `corfu-separator' inserted
-  (corfu-preview-current 'insert)  ; Preview first candidate. Insert on input if only one
-  (corfu-preselect-first t)        ; Preselect first candidate?
-
-  ;; Other
-  (corfu-echo-documentation nil)        ; Already use corfu-popupinfo
-
-  :init
-  ;; see https://github.com/minad/corfu#completing-in-the-eshell-or-shell
-  (add-hook 'eshell-mode-hook
-            (lambda ()
-              (setq-local corfu-auto nil)
-              (corfu-mode)))
-  :config
-  (global-corfu-mode))
-#+end_src
-
-**** corfu-popupinfo
-
-#+begin_src emacs-lisp
-(use-package corfu-popupinfo
-  :after corfu
-  :hook (corfu-mode . corfu-popupinfo-mode)
-  :bind (:map corfu-map
-              ("M-n" . corfu-popupinfo-scroll-up)
-              ("M-p" . corfu-popupinfo-scroll-down)
-              ([remap corfu-show-documentation] . corfu-popupinfo-toggle))
-  :custom
-  (corfu-popupinfo-delay 0.5)
-  (corfu-popupinfo-max-width 70)
-  (corfu-popupinfo-max-height 20)
-  ;; Also here to be extra-safe that this is set when `corfu-popupinfo' is
-  ;; loaded. I do not want documentation shown in both the echo area and in
-  ;; the `corfu-popupinfo' popup.
-  (corfu-echo-documentation nil))
-#+end_src
-*** cape
-
-#+begin_src emacs-lisp
-(use-package cape
-  :demand t
-  :ensure t
-  :bind (("C-c . p" . completion-at-point)
-	 ("C-c . h" . cape-history)
-	 ("C-c . f" . cape-file)
-	 ("C-c . a" . cape-abbrev)
-	 ("C-c . l" . cape-line)
-	 ("C-c . w" . cape-dict)
-	 ("C-c . r" . cape-rfc1345))
-  :init
-  ;; Add `completion-at-point-functions', used by `completion-at-point'.
-  (add-to-list 'completion-at-point-functions #'cape-file)
-  (add-to-list 'completion-at-point-functions #'cape-abbrev))
-#+end_src
-*** marginalia
-#+begin_src emacs-lisp
-  (use-package marginalia
-    :ensure t
-    ;; Either bind `marginalia-cycle' globally or only in the minibuffer
-    :bind (:map minibuffer-local-map
-         ("M-A" . marginalia-cycle))
-
-    :init
-    ;; Must be in the :init section of use-package such that the mode gets
-    ;; enabled right away. Note that this forces loading the package.
-    (marginalia-mode))
-#+end_src
-*** orderless
-#+begin_src emacs-lisp
-  (use-package orderless
-    :demand t
-    :ensure t
-    :custom
-    (completion-styles '(orderless basic))
-    (completion-category-defaults nil))
-#+end_src
-*** vertico
-#+begin_src emacs-lisp
-  (use-package vertico
-    :ensure t
-    :config
-    (vertico-mode))
-#+end_src
-*** yasnippet
-#+begin_src emacs-lisp
-(use-package yasnippet
-  :ensure t
-  :defer t
-  :diminish
-  :hook ((prog-mode . yas-minor-mode))
-  :config
-  (yas-reload-all))
-#+end_src
-
-** dired
-
-#+begin_src emacs-lisp
-(use-package dired
-  :diminish
-  :bind (:map dired-mode-map
-              ("j"     . dired)
-              ("z"     . pop-window-configuration)
-              ("^"     . dired-up-directory)
-              ("q"     . pop-window-configuration)
-              ("M-!"   . shell-command)
-              ("<tab>" . dired-next-window))
-  :custom
-  (dired-clean-up-buffers-too nil)
-  (dired-dwim-target t)
-  (dired-hide-details-hide-information-lines nil)
-  (dired-hide-details-hide-symlink-targets nil)
-  (dired-listing-switches "-lah")
-  (dired-no-confirm
-   '(byte-compile chgrp chmod chown copy hardlink symlink touch))
-  (dired-omit-mode nil t)
-  (dired-omit-size-limit 60000)
-  (dired-recursive-copies 'always)
-  (dired-recursive-deletes 'always)
-  :functions (dired-dwim-target-directory))
-#+end_src
-
-** direnv
-Invokes [[https://direnv.net/][direnv]] to obtain environment for the current file.
-
-#+begin_src emacs-lisp
-  (use-package direnv
-    :ensure t
-    :custom
-    (direnv-always-show-summary nil)
-    :config
-    (direnv-mode))
-#+end_src
-
-** docker
-
-#+begin_src emacs-lisp
-(use-package docker
-  :bind ("C-c d" . docker)
-  :diminish
-  :init
-  (use-package docker-image   :commands docker-images)
-  (use-package docker-volume  :commands docker-volumes)
-  (use-package docker-network :commands docker-containers)
-  (use-package docker-compose :commands docker-compose)
-
-  (use-package docker-container
-    :commands docker-containers
-    :custom
-    (docker-containers-shell-file-name "/bin/bash")
-    (docker-containers-show-all nil)))
-#+end_src
-
-*** docker-compose-mode
-
-#+begin_src emacs-lisp
-(use-package docker-compose-mode
-  :ensure t
-  :mode "docker-compose.*\.yml\\'")
-#+end_src
-
-*** dockerfile-mode
-
-#+begin_src emacs-lisp
-(use-package dockerfile-mode
-  :ensure t
-  :mode "Dockerfile[a-zA-Z.-]*\\'")
-#+end_src
-
-** emacs
-
-#+begin_src emacs-lisp
-  (use-package emacs
-    :bind* ("M-j" . join-line)
-
-    :custom-face
-    (cursor ((t (:background "hotpink"))))
-    ;; (highlight ((t (:background "blue4"))))
-    ;; (minibuffer-prompt ((t (:foreground "grey80"))))
-    ;; (mode-line-inactive ((t (:background "grey50"))))
-    (nobreak-space ((t nil)))
-
-    :custom
-    (auto-save-default nil)                     ;; don't auto save files
-    (auto-save-list-file-prefix nil)            ;; no backups
-    (create-lockfiles nil)                      ;; don't use a lock file
-    (confirm-kill-emacs #'yes-or-no-p)          ;; ask before killing emacs
-    (make-backup-files nil)                     ;; really no backups
-    (minibuffer-message-timeout 0.5)            ;; How long to display an echo-area message
-    (next-screen-context-lines 5)               ;; scroll 5 lines at a time
-    (require-final-newline t)                   ;; ensure newline exists at the end of the file
-    (ring-bell-function 'ignore)                ;; really no bell
-    (tab-always-indent 'complete)               ;; when using TAB, always indent
-    (visible-bell nil)                          ;; no bell
-    (column-number-mode t)                      ;; show column number in the mode line
-    (electric-pair-mode 1)                      ;; matches parens and brackets
-    (indent-tabs-mode nil)                      ;; turn off tab indentation
-    (cursor-type 'box)                          ;; cursor is a horizontal bar
-    (delete-by-moving-to-trash t)               ;; delete files by moving them to the trash
-    (initial-scratch-message "")                ;; empty scratch buffer
-    (garbage-collection-messages t)             ;; log when the gc kicks in
-
-    ;; bytecomp.el
-    (byte-compile-verbose nil)
-
-    ;; prog-mode.el
-    (prettify-symbols-unprettify-at-point 'right-edge)
-
-    ;; startup.el
-    (auto-save-list-file-prefix (user-data "auto-save-list/.saves-"))
-    (initial-buffer-choice t)
-    (initial-major-mode 'fundamental-mode)
-    (initial-scratch-message "")
-
-    (user-full-name "Franck Cuny")
-    (user-mail-address "franck@fcuny.net")
-    (add-log-mailing-address "franck@fcuny.net")
-
-    (history-length 200)
-    (history-delete-duplicates t)
-    (completion-ignored-extensions
-     '(".class"
-       ".cp"
-       ".elc"
-       ".fmt"
-       ".git/"
-       ".pyc"
-       ".so"
-       "~"))
-
-    ;; paragraphs.el
-    (sentence-end-double-space nil)
-
-    ;; switch to view-mode whenever you are in a read-only buffer (e.g.
-    ;; switched to it using C-x C-q).
-    (view-read-only t)
-
-    ;; window.el
-    (switch-to-buffer-preserve-window-point t)
-
-    ;; warnings.el
-    (warning-minimum-log-level :error)
-
-    ;; frame.el
-    (window-divider-default-bottom-width 1)
-    (window-divider-default-places 'bottom-only)
-
-    ;; paren.el
-    (show-paren-delay 0)
-    (show-paren-highlight-openparen t)
-    (show-paren-when-point-inside-paren t)
-    (show-paren-when-point-in-periphery t)
-
-    :config
-    (add-hook 'after-save-hook
-              #'executable-make-buffer-file-executable-if-script-p))
-#+end_src
-
-** eshell
-#+begin_src emacs-lisp
-(use-package eshell
-  :commands (eshell eshell-command)
-  :custom
-  (eshell-directory-name (emacs-path "eshell"))
-  (eshell-hist-ignoredups t)
-  (eshell-history-size 50000)
-  (eshell-ls-dired-initial-args '("-h"))
-  (eshell-ls-exclude-regexp "~\\'")
-  (eshell-ls-initial-args "-h")
-  (eshell-modules-list
-   '(eshell-alias
-     eshell-basic
-     eshell-cmpl
-     eshell-dirs
-     eshell-glob
-     eshell-hist
-     eshell-ls
-     eshell-pred
-     eshell-prompt
-     eshell-rebind
-     eshell-script
-     eshell-term
-     eshell-unix
-     eshell-xtra))
-  (eshell-prompt-function
-   (lambda nil
-     (concat (abbreviate-file-name (eshell/pwd))
-             (if (= (user-uid) 0)
-                 " # " " $ "))))
-  (eshell-save-history-on-exit t)
-  (eshell-stringify-t nil)
-  (eshell-term-name "ansi")
-
-  :preface
-  (defun eshell-initialize ()
-    (add-hook 'eshell-expand-input-functions #'eshell-spawn-external-command)
-
-  :init
-  (add-hook 'eshell-first-time-mode-hook #'eshell-initialize)))
-#+end_src
-
-** flymake
-
-#+begin_src emacs-lisp
-(use-package flymake
-  :bind (("C-c ! n" . flymake-goto-next-error)
-         ("C-c ! p" . flymake-goto-next-error))
-  :custom
-  (flymake-start-on-save-buffer t)
-  (flymake-fringe-indicator-position 'left-fringe)
-  (flymake-suppress-zero-counters t)
-  (flymake-proc-compilation-prevents-syntax-check t)
-  (elisp-flymake-byte-compile-load-path load-path))
-#+end_src
-
-** font
-Somehow I need to set the font to a higher height on MacOS.
-
-#+BEGIN_SRC emacs-lisp
-;; use various monaspace fonts
-;; https://monaspace.githubnext.com
-(set-face-attribute 'default nil
-                    :font "Monaspace Neon"
-                    :height 150)
-
-(set-face-attribute 'fixed-pitch nil
-                    :font "Monaspace Neon"
-                    :height 150)
-
-(set-face-attribute 'variable-pitch nil
-                    :font "Monaspace Radon"
-                    :height 150)
-
-(custom-set-faces
- '(font-lock-comment-face ((t (:font "Monaspace Radon" :italic t :height 1.0)))))
-#+END_SRC
-
-** fringe
-
-#+begin_src emacs-lisp
-(use-package fringe
-  :config
-  ;;; no fringe on the right side
-  (set-fringe-mode '(8 . 0)))
-#+end_src
-
-** git-link
-
-A convenient package to create link to a code location in GitHub, or other forges. This is very useful to get a link and share with others when looking at some code.
-
-#+begin_src emacs-lisp
-  (use-package git-link
-    :defines git-link-remote-alist
-    :ensure t
-    :bind ("C-c Y" . git-link)
-    :commands (git-link git-link-commit git-link-homepage)
-
-    :custom
-    (git-link-open-in-browser t)
-
-    :preface
-    (defun git-link-fcuny-net (hostname dirname filename branch commit start end)
-      (format "http://git.fcuny.net/%s/tree/%s?id=%s#n%s"
-              (replace-regexp-in-string "^r/\\(.*\\)" "\\1.git" dirname)
-              filename
-              commit
-              start))
-
-    (defun git-link-commit-fcuny-net (hostname dirname commit)
-      (format "http://git.fcuny.net/%s/commit/?id=%s"
-              (replace-regexp-in-string "^r/\\(.*\\)" "\\1.git" dirname)
-              commit))
-
-    :config
-    (add-to-list 'git-link-remote-alist '("git\\.fcuny\\.net" git-link-fcuny-net))
-    (add-to-list 'git-link-commit-remote-alist '("git\\.fcuny\\.net" git-link-commit-fcuny-net))
-
-    ;; sets up roblox git enterprise as a git-link handler
-    (add-to-list 'git-link-remote-alist '("github\\.rblx\\.com" git-link-github))
-    (add-to-list 'git-link-commit-remote-alist '("github\\.rblx\\.com" git-link-commit-github)))
-#+end_src
-
-** ibuffer
-
-#+begin_src emacs-lisp
-(use-package ibuffer
-  :bind ("C-x C-b" . ibuffer)
-  :custom
-  (ibuffer-default-display-maybe-show-predicates t)
-  (ibuffer-expert t)
-  (ibuffer-formats
-   '((mark modified read-only " "
-           (name 16 -1)
-           " "
-           (size 6 -1 :right)
-           " "
-           (mode 16 16)
-           " " filename)
-     (mark " "
-           (name 16 -1)
-           " " filename)))
-  (ibuffer-maybe-show-regexps nil)
-  (ibuffer-saved-filter-groups
-   '(("default"
-      ("Magit"
-       (or
-        (mode . magit-status-mode)
-        (mode . magit-log-mode)
-        (name . "\\*magit")
-        (name . "magit-")
-        (name . "git-monitor")))
-      ("Commands"
-       (or
-        (mode . shell-mode)
-        (mode . eshell-mode)
-        (mode . term-mode)
-        (mode . compilation-mode)))
-      ("Rust"
-       (or
-        (mode . rust-mode)
-        (mode . cargo-mode)
-        (name . "\\*Cargo")
-        (name . "^\\*rls\\(::stderr\\)?\\*")
-        (name . "eglot")))
-      ("Nix"
-       (mode . nix-mode))
-      ("Lisp"
-       (mode . emacs-lisp-mode))
-      ("Dired"
-       (mode . dired-mode))
-      ("Org"
-       (or
-        (name . "^\\*Calendar\\*$")
-        (name . "^\\*Org Agenda")
-        (name . "^ \\*Agenda")
-        (name . "^diary$")
-        (mode . org-mode)))
-      ("Emacs"
-       (or
-        (name . "^\\*scratch\\*$")
-        (name . "^\\*Messages\\*$")
-        (name . "^\\*\\(Customize\\|Help\\)")
-        (name . "\\*\\(Echo\\|Minibuf\\)"))))))
-  (ibuffer-show-empty-filter-groups nil)
-  (ibuffer-shrink-to-minimum-size t t)
-  (ibuffer-use-other-window t)
-  :init
-  (add-hook 'ibuffer-mode-hook
-            #'(lambda ()
-                (ibuffer-switch-to-saved-filter-groups "default"))))
-#+end_src
-
-** indent
-
-#+begin_src emacs-lisp
-(use-package indent
-  :commands indent-according-to-mode
-  :custom
-  (tab-always-indent 'complete))
-#+end_src
-
-** ispell
-
-#+begin_src emacs-lisp
-  (use-package ispell
-    :custom
-    (ispell-program-name (executable-find "aspell"))
-    (ispell-dictionary "en_US")
-    (ispell-extra-args '("--camel-case")))
-#+end_src
-
-** jq-mode
-
-#+begin_src emacs-lisp
-  (use-package jq-mode
-    :ensure t
-    :mode "\\.jq\\'")
-#+end_src
-
-** js2-mode
-** languages
-*** eglot
-After experimenting with [[https://emacs-lsp.github.io/lsp-mode/][lsp-mode]] and [[https://github.com/joaotavora/eglot][eglot]] I decided to go with eglot for LSP integration.
-
-For languages where I want to use LSP, I need to add ~:hook (nix-mode . englot-ensure)~ in the ~use-package~ definition for the language.
-
-#+begin_src emacs-lisp
-(use-package eglot
-  :ensure t
-  :after yasnippet
-  :bind (:map eglot-mode-map
-              ("C-c l a" . eglot-code-actions)
-              ("C-c l r" . eglot-rename))
-  :config
-  (setq-default eglot-workspace-configuration
-                '((gopls
-		   (usePlaceholders . t)
-		   (staticcheck . t)
-		   (completeUnimported . t))))
-
-  ;; uses https://github.com/oxalica/nil for the LSP server instead of rnix
-  (add-to-list 'eglot-server-programs '(nix-mode . ("nixd"))))
-#+end_src
-*** tree-sitter
-
-#+begin_src emacs-lisp
-(use-package tree-sitter
-  :ensure t
-  :config
-  (global-tree-sitter-mode))
-#+end_src
-
-**** tree-sitter-langs
-
-#+begin_src emacs-lisp
-(use-package tree-sitter-langs
-  :after tree-sitter
-  :ensure t)
-#+end_src
-
-*** lisp-mode
-
-**** elisp-mode
-
-#+begin_src emacs-lisp
-(use-package emacs-lisp-mode
-  :bind (:map emacs-lisp-mode-map
-              ("C-c C-r" . eval-region)
-              ("C-c C-d" . eval-defun)
-              ("C-c C-b" . eval-buffer))
-  :hook ((emacs-lisp-mode . flymake-mode)))
-#+end_src
-
-**** eldoc
-
-#+begin_src emacs-lisp
-(use-package eldoc
-  :diminish
-  :hook ((c-mode-common emacs-lisp-mode) . eldoc-mode)
-  :custom
-  (eldoc-idle-delay 1)
-  (eldoc-documentation-strategy #'eldoc-documentation-default)
-  (eldoc-echo-area-use-multiline-p 3)
-  (eldoc-echo-area-prefer-doc-buffer 'maybe)
-  (eldoc-echo-area-display-truncation-message nil))
-#+end_src
-
-*** hcl-mode
-
-#+begin_src emacs-lisp
-  (use-package hcl-mode
-    :ensure t
-    :mode "\.nomad\\'")
-#+end_src
-
-*** json-mode
-
-#+begin_src emacs-lisp
-(use-package json-mode
-  :mode "\\.json\\'")
-#+end_src
-
-**** json-reformat
-
-#+begin_src emacs-lisp
-(use-package json-reformat
-  :ensure t
-  :after json-mode)
-#+end_src
-
-*** go-mode
-
-#+begin_src emacs-lisp
-(use-package go-mode
-  :ensure t
-  :defer t
-  :hook ((go-mode . tree-sitter-hl-mode)
-         (go-mode . eglot-ensure)
-         (go-mode . (lambda () (setq tab-width 4)))
-         (go-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t))))
-  :bind (:map go-mode-map
-              ("C-c C-c" . compile)))
-#+end_src
-
-**** gotest
-
-#+begin_src emacs-lisp
-(use-package gotest
-  :ensure t
-  :after go-mode
-  :custom
-  (go-test-verbose t))
-#+end_src
-
-*** nix-mode
-
-#+begin_src emacs-lisp
-  (use-package nix-mode
-    :ensure t
-    :hook ((nix-mode . eglot-ensure)
-           (nix-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t))))
-    :custom
-    (nix-indent-function 'nix-indent-line))
-#+end_src
-
-*** protobuf-mode
-
-#+begin_src emacs-lisp
-  (use-package protobuf-mode
-    :ensure t
-    :mode "\\.proto\\'")
-#+end_src
-
-*** python-mode
-
-Enable eglot and tree-sitter when working with python.
-
-#+begin_src emacs-lisp
-(use-package python-mode
-  :hook ((python-mode . tree-sitter-hl-mode)
-         (python-mode . eglot-ensure))
-  :interpreter "python"
-  :bind (:map python-mode-map
-              ("C-c c")
-              ("C-c C-z" . python-shell)))
-#+end_src
-
-**** blacken
-
-[[https://pypi.org/project/black/][black]] is a code formatter for python.
-
-#+begin_src emacs-lisp
-(use-package blacken
-  :ensure t
-  :hook (python-mode . blacken-mode))
-#+end_src
-
-**** isort
-
-[[https://pypi.org/project/isort/][Sort imports]].
-
-#+begin_src emacs-lisp
-  (use-package py-isort
-    :ensure t
-    :commands (py-isort-buffer py-isort-region))
-#+end_src
-
-*** ruby-mode
-
-#+begin_src emacs-lisp
-  (use-package ruby-mode
-    :mode "\\.rb\\'"
-    :interpreter "ruby"
-    :bind (:map ruby-mode-map
-                ("<return>" . my-ruby-smart-return))
-    :preface
-    (defun my-ruby-smart-return ()
-      (interactive)
-      (when (memq (char-after) '(?\| ?\" ?\'))
-        (forward-char))
-      (call-interactively 'newline-and-indent)))
-#+end_src
-
-*** sh-script
-
-#+begin_src emacs-lisp
-(use-package sh-script
-  :defer t
-  :preface
-  (defvar sh-script-initialized nil)
-
-  (defun initialize-sh-script ()
-    (unless sh-script-initialized
-      (setq sh-script-initialized t)
-      (info-lookup-add-help :mode 'shell-script-mode
-                            :regexp ".*"
-                            :doc-spec '(("(bash)Index")))))
-  :init
-  (add-hook 'shell-mode-hook #'initialize-sh-script))
-#+end_src
-
-*** terraform-mode
-
-#+begin_src emacs-lisp
-(use-package terraform-mode
-  :ensure t
-  :mode "\.tf\\'")
-#+end_src
-
-*** toml-mode
-
-#+begin_src emacs-lisp
-(use-package toml-mode
-  :defer t
-  :ensure t)
-#+end_src
-
-*** yaml-mode
-
-#+begin_src emacs-lisp
-(use-package yaml-mode
-  :ensure t
-  :mode "\\.ya?ml\\'")
-#+end_src
-
-** MacOS specific
-
-#+begin_src emacs-lisp
-(when (memq window-system '(mac ns))
-  (add-to-list 'default-frame-alist '(fullscreen . maximized))
-  (add-to-list 'default-frame-alist '(ns-appearance . nil))
-  (add-to-list 'default-frame-alist '(ns-transparent-titlebar . nil))
-  (when (boundp 'ns-use-native-fullscreen)
-    (setq ns-use-native-fullscreen nil))
-  (when (boundp 'mac-allow-anti-aliasing)
-    (setq mac-allow-anti-aliasing t)))
-#+end_src
-
-** path setup
-This needs to be done before we configure =magit=. If done later, on MacOS, and I'm running =nix=, for some reasons emacs try to pick =git= from =/usr/bin/git= instead of =/Users/fcuny/.nix-profile/bin/git=.
-
-#+begin_src emacs-lisp
-(use-package exec-path-from-shell
-  :ensure t
-  :demand t
-  :if (memq window-system '(mac ns))
-  :config
-  (exec-path-from-shell-initialize))
-#+end_src
-
-** magit
-
-#+begin_src emacs-lisp
-  (use-package magit
-    :defer t
-    :ensure t
-    :bind (("C-x g" . magit-status)
-           ("C-x G" . magit-status-with-prefix))
-    :custom
-    (magit-diff-options nil)
-    (magit-diff-refine-hunk t)
-    (magit-fetch-arguments nil)
-    (magit-log-section-commit-count 10)
-    (magit-pre-refresh-hook nil)
-    (magit-process-popup-time 15)
-    (magit-clone-default-directory "~/workspace/")
-    (magit-section-initial-visibility-alist '((untracked . hide)))
-    :hook (magit-mode . hl-line-mode)
-    :config
-    (use-package magit-commit
-      :defer t
-      :config
-      (use-package git-commit
-        :custom
-        (git-commit-major-mode 'markdown-mode)
-        (git-commit-setup-hook
-         '(git-commit-save-message
-           git-commit-turn-on-auto-fill
-           git-commit-turn-on-flyspell
-           bug-reference-mode))))
-
-    (use-package magit-status
-      :defer t
-      :config
-      (dolist (func '(magit-insert-unpushed-to-upstream-or-recent
-                      magit-insert-unpulled-from-pushremote
-                      magit-insert-unpulled-from-upstream
-                      ))
-        (remove-hook 'magit-status-sections-hook func))
-
-      (dolist (func '(magit-insert-diff-filter-header
-                      magit-insert-tags-header))
-        (remove-hook 'magit-status-headers-hook func))))
-#+end_src
-
-** markdown-mode
-
-#+begin_src emacs-lisp
-(use-package markdown-mode
-  :mode (("\\`README\\.md\\'" . gfm-mode)
-         ("\\.md\\'"          . markdown-mode)
-         ("\\.markdown\\'"    . markdown-mode))
-  :custom
-  (markdown-command "pandoc -f markdown_github+smart")
-  (markdown-command-needs-filename t)
-  (markdown-enable-math t)
-  (markdown-open-command "marked")
-  :init
-  (setq markdown-command "multimarkdown"))
-#+end_src
-
-*** markdown-preview-mode
-
-#+begin_src emacs-lisp
-  (use-package markdown-preview-mode
-    :ensure t
-    :after markdown-mode
-    :config
-    (setq markdown-preview-stylesheets
-	  (list (concat "https://github.com/dmarcotte/github-markdown-preview/"
-			"blob/master/data/css/github.css"))))
-#+end_src
-
-** midnight
-
-#+begin_src emacs-lisp
-(use-package midnight
-  :demand t
-  :bind ("C-c z" . clean-buffer-list)
-  :custom
-  (midnight-delay 18000)
-  (clean-buffer-list-kill-never-buffer-names
-   '("*scratch*"
-     "*Messages*"
-     "*server*"
-     "*Group*"
-     "*Org Agenda*"
-     "todo.org"))
-  (clean-buffer-list-kill-never-regexps
-   '("^ \\*Minibuf-.*\\*$"
-     "^\\*Summary"
-     "^\\*Article" "^#"))
-  (clean-buffer-list-kill-regexps '(".*"))
-  :config
-  (midnight-mode t))
-#+end_src
-
-** my-cheeseboard
-
-get the pizzas for this week at cheeseboard.
-
-#+begin_src emacs-lisp
-(use-package my-cheeseboard)
-#+end_src
-
-** my-uptime
-
-an uptime / SLO calculator.
-
-#+begin_src emacs-lisp
-(use-package my-uptime
-  :init
-  (add-to-list 'display-buffer-alist '("\\*slo-calculator\\*"
-                                       (display-buffer-in-side-window)
-                                       (side . left)
-                                       (slot . 0)
-                                       (window-width . 0.35))))
-#+end_src
-
-** org-mode
-
-#+begin_src emacs-lisp
-  (use-package org
-    :hook
-    (org-mode . turn-on-flyspell)
-    (org-mode . visual-line-mode)
-    (org-mode . org-indent-mode)
-    :custom
-    ;;; general settings
-    (org-startup-folded t)
-    (org-startup-indented t)
-    (org-hide-emphasis-markers t)
-    (org-hide-leading-stars t)
-    (org-pretty-entities t)
-    (org-return-follows-link t)
-    (org-startup-with-inline-images t)
-    (org-export-backends '(html md))
-    (org-imenu-depth 4)
-    (org-insert-heading-respect-content t)
-    (org-outline-path-complete-in-steps nil)
-    (org-src-fontify-natively t)
-    (org-src-preserve-indentation t)
-    (org-src-tab-acts-natively t)
-    (org-src-window-setup 'current-window)
-    (org-yank-adjusted-subtrees t)
-    (org-structure-template-alist
-        '(("s" . "src")
-          ("E" . "src emacs-lisp")
-          ("p" . "src python")
-          ("e" . "example")
-          ("q" . "quote")
-          ("V" . "verbatim")))
-    :config
-    (font-lock-add-keywords 'org-mode
-                            '(("^ *\\(-\\) "
-                               (0 (ignore (compose-region (match-beginning 1) (match-end 1) "•")))))))
-#+end_src
-
-*** org-bullet
-
-This is to make =org-mode= document looks a bit nicer.
-
-#+begin_src emacs-lisp
-(use-package org-bullets
-  :ensure t
-  :hook (org-mode . org-bullets-mode))
-#+end_src
-
-*** org-auto-tangle
-
-#+begin_src emacs-lisp
-(use-package org-auto-tangle
-  :ensure t
-  :hook (org-mode . org-auto-tangle-mode))
-#+end_src
-
-*** org-babel
-
-#+begin_src emacs-lisp
-(use-package org-babel
-  :no-require t
-  :after (org)
-  :config
-  (org-babel-do-load-languages
-   'org-babel-load-languages
-   '((python     . t)
-     (emacs-lisp . t)
-     (calc       . t)
-     (shell      . t)
-     (sql        . t)
-     (dot        . t)))
-
-  (remove-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory)
-
-  (advice-add 'org-babel-edit-prep:emacs-lisp :after
-              #'(lambda (_info) (run-hooks 'emacs-lisp-mode-hook))))
-#+end_src
-
-*** ox
-**** ox-gfm
-
-#+begin_src emacs-lisp
-(use-package ox-gfm
-  :ensure t
-  :after org)
-#+end_src
-
-**** ox-md
-
-#+begin_src emacs-lisp
-(use-package ox-md
-  :after org)
-#+end_src
-
-**** ox-pandoc
-
-#+begin_src emacs-lisp
-(use-package ox-pandoc
-  :ensure t
-  :after org
-  :preface
-  (defun markdown-to-org-region (start end)
-    "Convert region from markdown to org, replacing selection"
-    (interactive "r")
-    (shell-command-on-region start end "pandoc -f markdown -t org" t t)))
-#+end_src
-
-** project
-#+begin_src emacs-lisp
-  (use-package project
-  :ensure nil
-  :custom
-  (project-switch-commands
-   '((project-dired "Root" ?d)
-     (project-find-file "File" ?f)
-     (project-switch-to-buffer "Buffer" ?b)
-     (project-eshell "Shell" ?e)
-     (magit-project-status "Git" ?g)))
-  :init
-  (setq-default project-list-file (user-data "projects.eld")))
-#+end_src
-
-** recentf
-
-#+begin_src emacs-lisp
-(use-package recentf
-  :demand t
-  :commands (recentf-mode
-             recentf-add-file
-             recentf-apply-filename-handlers)
-  :custom
-  (recentf-auto-cleanup 60)
-  (recentf-exclude
-   '("~\\'" "\\`out\\'" "\\.log\\'" "^/[^/]*:" "\\.el\\.gz\\'" "\\.gz\\'"))
-  (recentf-max-saved-items 2000)
-  (recentf-save-file (user-data "recentf"))
-  :preface
-  :config
-  (recentf-mode 1))
-#+end_src
-
-** restclient
-
-Open a file with the extension =.rest=, and start writing queries in it. For example:
-
-#+begin_example
-GET https://api.github.com
-User-Agent: Emacs Restclient
-#+end_example
-
-Then one of the following binding:
-| binding | action                                             |
-|---------+----------------------------------------------------|
-| =C-c C-c= | run the query                                      |
-| =C-c C-v= | same as above but switch focus to the other buffer |
-
-#+begin_src emacs-lisp
-(use-package restclient
-  :ensure t
-  :mode ("\\.rest\\'" . restclient-mode))
-#+end_src
-
-** rg
-
-#+begin_src emacs-lisp
-  (use-package rg
-    :ensure t
-    :custom ((rg-group-result t)
-             (rg-show-columns t)
-             (rg-align-line-number-field-length 3)
-             (rg-align-column-number-field-length 3)
-             (rg-align-line-column-separator "#")
-             (rg-align-position-content-separator "|")
-             (rg-hide-command nil)
-             (rg-align-position-numbers t)
-             (rg-command-line-flags '("--follow"))))
-#+end_src
-
-** savehist
-
-#+begin_src emacs-lisp
-(use-package savehist
-  :unless noninteractive
-  :custom
-  (savehist-additional-variables
-   '(file-name-history
-     kmacro-ring
-     compile-history
-     compile-command))
-  (savehist-autosave-interval 60)
-  (savehist-file (user-data "history"))
-  (savehist-ignored-variables
-   '(load-history
-     flyspell-auto-correct-ring
-     org-roam-node-history
-     magit-revision-history
-     org-read-date-history
-     query-replace-history
-     yes-or-no-p-history
-     kill-ring))
-  (savehist-mode t)
-  :config
-  (savehist-mode 1))
-#+end_src
-
-** saveplace
-
-#+begin_src emacs-lisp
-(use-package saveplace
-  :unless noninteractive
-  :custom
-  (save-place-file (user-data "places"))
-  :config
-  (save-place-mode 1))
-#+end_src
-
-** theme
-
-*** modus-themes
-
-This theme is clean and readable. The [[https://protesilaos.com/emacs/modus-themes][online documentation]] is pretty detailed too.
-
-#+begin_src emacs-lisp
-(use-package modus-themes
-  :ensure t
-  :custom
-  ;; Syntax Highlighting
-  (modus-themes-bold-constructs t)
-  (modus-operandi-palette-overrides '((comment red-faint)
-                                      (string "#101010")
-                                      (bg-main "#FFFCF6")))
-
-  (modus-themes-italic-constructs t)
-
-  ;; Use mixed fonts
-  (modus-themes-mixed-fonts t)
-  (modus-themes-variable-pitch-ui t)
-
-  ;; Enhance minibuffer completions
-  (modus-themes-prompts '(italic bold))
-  (modus-themes-completions '((matches . (extrabold))
-                              (selection . (semibold italic text-also))))
-
-  ;; Org Mode
-  ;;; Make headings in org files more distinct
-  (modus-themes-headings '((t . (background bold rainbow 1))))
-  ;;; Tint the background of code blocks in org files
-  (modus-themes-org-blocks 'tinted-background)
-  ;;; Make tags less colorful and tables look the same as
-  ;;; the default foreground.
-  (prose-done cyan-cooler)
-  (prose-tag fg-dim)
-  (prose-table fg-main)
-
-  ;; Make the fringe more intense
-  (modus-themes-common-palette-overrides '((fringe bg-active)))
-
-  :config
-  (load-theme 'modus-operandi t))
-#+end_src
-
-*** COMMENT standard-themes
-
-I like the default theme, but there's not enough contrast. The package =standard-themes= fix this problem. The full documentation can be [[https://protesilaos.com/emacs/standard-themes][read online]].
-
-#+begin_src emacs-lisp
-(use-package standard-themes
-  :ensure t
-  :init
-  (setq standard-themes-bold-constructs t
-	standard-themes-italic-constructs t
-	standard-themes-mixed-fonts t
-	standard-themes-variable-pitch-ui nil
-	standard-themes-mode-line-accented t
-	;; Accepts a symbol value:
-	standard-themes-fringes 'intense
-	;; The following accept lists of properties
-	standard-themes-links '(italic neutral-underline)
-	standard-themes-region '(no-extend neutral intense)
-	standard-themes-prompts '(bold italic)
-        standard-themes-headings (quote ((1 . (bold 1.2))
-                                         (2 . (regular 1.1))
-                                         (agenda-date (1.1))
-                                         (agenda-structure (regular 1.1)))))
-  (load-theme 'standard-light :no-confirm))
-#+end_src
-
-** time
-
-#+begin_src emacs-lisp
-(use-package time
-  :custom
-  (display-time-interval 60)
-  (display-time-mode t)
-  (display-time-24hr-format t)
-  (display-time-day-and-date t)
-  (display-time-default-load-average nil)
-  (world-clock-list t)
-  (world-clock-timer-enable t)
-  (world-clock-timer-second 60)
-  ;; UTC      => 02:42 +0000  Wednesday 20 April
-  ;; Berkeley => 19:42 -0700  Tuesday 19 April
-  (world-clock-time-format "%R %z  %A %d %B")
-  (zoneinfo-style-world-list '(("UTC" "UTC")
-                               ("America/Los_Angeles" "Berkeley")
-                               ("America/Denver" "Mountain Time")
-                               ("America/Chicago" "Central Time")
-                               ("America/New_York" "New York")
-                               ("Europe/London" "London")
-                               ("Europe/Paris" "Paris")))
-  :init
-  (add-to-list 'display-buffer-alist '("\\*wclock\\*"
-                                       (display-buffer-in-side-window)
-                                       (side . left)
-                                       (slot . 0)
-                                       (window-width . 0.35))))
-#+end_src
-
-** tramp
-
-#+begin_src emacs-lisp
-  (use-package tramp
-    :defer t
-    :custom
-    (tramp-default-method "ssh")
-    (tramp-auto-save-directory "~/.cache/emacs/backups")
-    (tramp-ssh-controlmaster-options "-o ControlMaster=auto -o ControlPath='tramp.%%C'")
-    :config
-    ;; Setting this with `:custom' does not take effect.
-    (setq tramp-persistency-file-name (user-data "tramp")))
-#+end_src
-
-** transient
-
-#+begin_src emacs-lisp
-(use-package transient
-  :defer t
-  :custom
-  (transient-history-file (user-data "transient/history.el"))
-  (transient-values-file (user-data "transient/values.el")))
-#+end_src
-
-** vc
-
-#+begin_src emacs-lisp
-(use-package vc
-  :defer t
-  :custom
-  (vc-command-messages t)
-  (vc-follow-symlinks t))
-#+end_src
-
-** which-key
-
-#+begin_src emacs-lisp
-(use-package which-key
-  :demand t
-  :diminish
-  :ensure t
-  :config
-  (which-key-mode))
-#+end_src
-
-** whitespace
-
-#+begin_src emacs-lisp
-(use-package whitespace
-  :diminish (global-whitespace-mode
-             whitespace-mode
-             whitespace-newline-mode)
-  :commands (whitespace-buffer
-             whitespace-cleanup
-             whitespace-mode
-             whitespace-turn-off)
-  :init
-  (dolist (hook '(prog-mode-hook text-mode-hook))
-    (add-hook hook #'whitespace-mode))
-  :custom
-  (whitespace-auto-cleanup t t)
-  (whitespace-rescan-timer-time nil t)
-  (whitespace-silent t t)
-  (whitespace-style '(face trailing space-before-tab))
-  :defines
-  (whitespace-auto-cleanup
-   whitespace-rescan-timer-time
-   whitespace-silent))
-#+end_src
-
-* Finalization
-#+begin_src emacs-lisp
-(report-time-since-load)
-
-;; Local Variables:
-;; byte-compile-warnings: (not docstrings lexical noruntime)
-;; End:
-#+end_src