commit 13821509148189b286103f9d58b37c789a44c3c4
Author: Michael Neuper <michael@michaelneuper.com>
Date: Thu, 14 Nov 2024 22:48:40 +0200
init
Diffstat:
| A | config.el | | | 887 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | config.org | | | 1191 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | init.el | | | 247 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | packages.el | | | 108 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 2433 insertions(+), 0 deletions(-)
diff --git a/config.el b/config.el
@@ -0,0 +1,887 @@
+;; Whenever you reconfigure a package, make sure to wrap your config in an
+;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
+
+;; (after! PACKAGE
+;; (setq x y))
+
+;; The exceptions to this rule:
+;; - Setting file/directory variables (like `org-directory')
+;; - Setting variables which explicitly tell you to set them before their
+;; package is loaded (see 'C-h v VARIABLE' to look up their documentation).
+;; - Setting doom variables (which start with 'doom-' or '+').
+
+;; Here are some additional functions/macros that will help you configure Doom.
+
+;; - `load!' for loading external *.el files relative to this one
+;; - `use-package!' for configuring packages
+;; - `after!' for running code after a package has loaded
+;; - `add-load-path!' for adding directories to the `load-path', relative to
+;; this file. Emacs searches the `load-path' when you load packages with
+;; `require' or `use-package'.
+;; - `map!' for binding new keys
+
+;; To get information about any of these functions/macros, move the cursor over
+;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
+;; This will open documentation for it, including demos of how they are used.
+;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
+;; etc).
+
+;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
+;; they are implemented.
+
+(use-package! gcmh
+ :init
+ (setq gcmh-idle-delay 5
+ gcmh-high-cons-threshold (* 256 1024 1024)) ; 256MB during idle
+ :config
+ (gcmh-mode 1))
+
+(setq gc-cons-threshold 200000000) ; previous 33554432
+
+(setq doom-localleader-key "SPC l"
+ doom-localleader-alt-key "M-SPC l")
+
+(setq auto-save-default t
+ make-backup-files t)
+
+(setq confirm-kill-emacs nil)
+
+(setq user-full-name "Michael Neuper"
+ user-mail-address "michael@michaelneuper.com")
+
+(load! "api-keys.el")
+
+(when IS-MAC
+ (setq mac-command-modifier 'meta
+ mac-option-modifier 'super
+ mac-right-option-modifier 'none))
+
+(after! auth-source
+ (setq auth-sources (nreverse auth-sources)))
+
+(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
+(add-to-list 'default-frame-alist '(ns-appearance . dark))
+
+(map! :leader
+ (:prefix "t"
+ :desc "Calc"
+ "c" #'calc
+ :desc "Eshell"
+ "e" #'+eshell/toggle
+ :desc "Scroll bar"
+ "s" #'scroll-bar-mode
+ :desc "Vterm"
+ "v" #'+vterm/toggle))
+
+(global-set-key (kbd "<f4>") #'deadgrep)
+(global-set-key (kbd "<f3>") #'ibuffer)
+
+(setq evil-split-window-below t
+ evil-vsplit-window-right t)
+
+(defadvice! prompt-for-buffers (&rest _)
+ :after '(evil-window-split evil-window-vsplit)
+ (consult-buffer))
+
+;; (scroll-bar-mode 1)
+;; (blink-cursor-mode 1)
+
+;; mac specific
+(when IS-MAC
+ (display-battery-mode 1))
+
+(setq doom-theme 'doom-gruvbox)
+
+;; (custom-set-faces!
+;; '(doom-dashboard-banner :inherit default)
+;; '(doom-dashboard-loaded :inherit default)
+;; '(dashboard-banner :inherrit default))
+
+;; (custom-set-faces!
+;; '(dashboard-startup-banner :inherit default))
+
+(setq display-line-numbers-type 'relative)
+(setq display-line-numbers-mode 'visual)
+(setq display-line-numbers 'visual)
+
+(setq display-fill-column-indicator-column 80)
+(add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)
+
+(when (version< "29.0.50" emacs-version)
+ (pixel-scroll-precision-mode 1))
+
+(cond (IS-LINUX
+ (setq doom-font (font-spec :family "Fira Code" :size 12.5)
+ doom-variable-pitch-font (font-spec :family "Noto Sans" :size 15)))
+ (IS-MAC
+ (setq doom-font (font-spec :family "JetBrainsMono Nerd Font" :size 15.5))
+ (setq doom-symbol-font (font-spec :family "Cascadia Code" :size 15.5))))
+
+(after! doom-themes
+ (setq doom-themes-enable-bold t))
+ ;; doom-themes-enable-italic t))
+
+;; (custom-set-faces!
+;; '(font-lock-comment-face :slant italic)
+;; '(font-lock-keyword-face :slant italic))
+
+;; (plist-put! +ligatures-extra-symbols
+;; :and nil
+;; :or nil
+;; :not nil
+;; :true nil
+;; :false nil
+;; :int nil
+;; :float nil
+;; :str nil
+;; :bool nil
+;; :list nil)
+
+(after! org
+ (setq org-ellipsis " ▾ ")
+ ;; (appendq! +ligatures-extra-symbols
+ ;; `(:checkbox "☐"
+ ;; :pending "◼"
+ ;; :checkedbox "☑"
+ ;; :list_property "∷"
+ ;; :em_dash "—"
+ ;; :ellipses "…"
+ ;; :arrow_right "→"
+ ;; :arrow_left "←"
+ ;; :begin_quote "❝"
+ ;; :end_quote "❞"
+ ;; :header "›"
+ ;; :priority_a ,(propertize "⚑" 'face 'all-the-icons-red)
+ ;; :priority_b ,(propertize "⬆" 'face 'all-the-icons-orange)
+ ;; :priority_c ,(propertize "■" 'face 'all-the-icons-yellow)
+ ;; :priority_d ,(propertize "⬇" 'face 'all-the-icons-green)
+ ;; :priority_e ,(propertize "❓" 'face 'all-the-icons-blue)
+ ;; :roam_tags nil
+ ;; :filetags nil))
+ (set-ligatures! 'org-mode
+ :merge t
+ :checkbox "[ ]"
+ :pending "[-]"
+ :checkedbox "[X]"
+ :list_property "::"
+ :em_dash "---"
+ :ellipsis "..."
+ :arrow_right "->"
+ :arrow_left "<-"
+ :title "#+title:"
+ :subtitle "#+subtitle:"
+ :author "#+author:"
+ :date "#+date:"
+ :property "#+property:"
+ :options "#+options:"
+ :startup "#+startup:"
+ :macro "#+macro:"
+ :html_head "#+html_head:"
+ :html "#+html:"
+ :latex_class "#+latex_class:"
+ :latex_header "#+latex_header:"
+ :beamer_header "#+beamer_header:"
+ :latex "#+latex:"
+ :attr_latex "#+attr_latex:"
+ :attr_html "#+attr_html:"
+ :attr_org "#+attr_org:"
+ :begin_quote "#+begin_quote"
+ :end_quote "#+end_quote"
+ :caption "#+caption:"
+ :header "#+header:"
+ :begin_export "#+begin_export"
+ :end_export "#+end_export"
+ :results "#+RESULTS:"
+ :property ":PROPERTIES:"
+ :end ":END:"
+ :priority_a "[#A]"
+ :priority_b "[#B]"
+ :priority_c "[#C]"
+ :priority_d "[#D]"
+ :priority_e "[#E]"
+ :roam_tags "#+roam_tags:"
+ :filetags "#+filetags:")
+ (plist-put +ligatures-extra-symbols :name "⁍"))
+
+(use-package! info-colors
+ :commands (info-colors-fontify-node))
+
+(add-hook 'Info-selection-hook
+ 'info-colors-fontify-node)
+
+(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu)
+
+
+(add-hook! '+doom-dashboard-functions :append
+ (insert "\n" (+doom-dashboard--center +doom-dashboard--width "Welcome back to Emacs!"))
+ (setq mode-line-format nil)
+ (hl-line-mode 0)
+ (read-only-mode +1))
+
+(setq-hook! '+doom-dashboard-mode-hook evil-normal-state-cursor (list nil))
+
+(defun my-weebery-is-always-greater ()
+ (let* ((banner '("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀"
+ "⢸⠉⣹⠋⠉⢉⡟⢩⢋⠋⣽⡻⠭⢽⢉⠯⠭⠭⠭⢽⡍⢹⡍⠙⣯⠉⠉⠉⠉⠉⣿⢫⠉⠉⠉⢉⡟⠉⢿⢹⠉⢉⣉⢿⡝⡉⢩⢿⣻⢍⠉⠉⠩⢹⣟⡏⠉⠹⡉⢻⡍⡇"
+ "⢸⢠⢹⠀⠀⢸⠁⣼⠀⣼⡝⠀⠀⢸⠘⠀⠀⠀⠀⠈⢿⠀⡟⡄⠹⣣⠀⠀⠐⠀⢸⡘⡄⣤⠀⡼⠁⠀⢺⡘⠉⠀⠀⠀⠫⣪⣌⡌⢳⡻⣦⠀⠀⢃⡽⡼⡀⠀⢣⢸⠸⡇"
+ "⢸⡸⢸⠀⠀⣿⠀⣇⢠⡿⠀⠀⠀⠸⡇⠀⠀⠀⠀⠀⠘⢇⠸⠘⡀⠻⣇⠀⠀⠄⠀⡇⢣⢛⠀⡇⠀⠀⣸⠇⠀⠀⠀⠀⠀⠘⠄⢻⡀⠻⣻⣧⠀⠀⠃⢧⡇⠀⢸⢸⡇⡇"
+ "⢸⡇⢸⣠⠀⣿⢠⣿⡾⠁⠀⢀⡀⠤⢇⣀⣐⣀⠀⠤⢀⠈⠢⡡⡈⢦⡙⣷⡀⠀⠀⢿⠈⢻⣡⠁⠀⢀⠏⠀⠀⠀⢀⠀⠄⣀⣐⣀⣙⠢⡌⣻⣷⡀⢹⢸⡅⠀⢸⠸⡇⡇"
+ "⢸⡇⢸⣟⠀⢿⢸⡿⠀⣀⣶⣷⣾⡿⠿⣿⣿⣿⣿⣿⣶⣬⡀⠐⠰⣄⠙⠪⣻⣦⡀⠘⣧⠀⠙⠄⠀⠀⠀⠀⠀⣨⣴⣾⣿⠿⣿⣿⣿⣿⣿⣶⣯⣿⣼⢼⡇⠀⢸⡇⡇⠇"
+ "⢸⢧⠀⣿⡅⢸⣼⡷⣾⣿⡟⠋⣿⠓⢲⣿⣿⣿⡟⠙⣿⠛⢯⡳⡀⠈⠓⠄⡈⠚⠿⣧⣌⢧⠀⠀⠀⠀⠀⣠⣺⠟⢫⡿⠓⢺⣿⣿⣿⠏⠙⣏⠛⣿⣿⣾⡇⢀⡿⢠⠀⡇"
+ "⢸⢸⠀⢹⣷⡀⢿⡁⠀⠻⣇⠀⣇⠀⠘⣿⣿⡿⠁⠐⣉⡀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠉⠓⠳⠄⠀⠀⠀⠀⠋⠀⠘⡇⠀⠸⣿⣿⠟⠀⢈⣉⢠⡿⠁⣼⠁⣼⠃⣼⠀⡇"
+ "⢸⠸⣀⠈⣯⢳⡘⣇⠀⠀⠈⡂⣜⣆⡀⠀⠀⢀⣀⡴⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢽⣆⣀⠀⠀⠀⣀⣜⠕⡊⠀⣸⠇⣼⡟⢠⠏⠀⡇"
+ "⢸⠀⡟⠀⢸⡆⢹⡜⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠋⣾⡏⡇⡎⡇⠀⡇"
+ "⢸⠀⢃⡆⠀⢿⡄⠑⢽⣄⠀⠀⠀⢀⠂⠠⢁⠈⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠄⡐⢀⠂⠀⠀⣠⣮⡟⢹⣯⣸⣱⠁⠀⡇"
+ "⠈⠉⠉⠉⠉⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁"))
+ (longest-line (apply #'max (mapcar #'length banner))))
+ (put-text-property
+ (point)
+ (dolist (line banner (point))
+ (insert (+doom-dashboard--center
+ +doom-dashboard--width
+ (concat line (make-string (max 0 (- longest-line (length line))) 32)))
+ "\n"))
+ 'face 'doom-dashboard-banner)))
+
+(setq +doom-dashboard-ascii-banner-fn #'my-weebery-is-always-greater)
+
+;; (setq fancy-splash-image (concat doom-private-dir "splashes/gnu/trancendent-gnu-medium.xpm"))
+
+;; (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")))
+;; (setq doom-fallback-buffer-name "*dashboard*")
+
+;; (use-package! dashboard
+;; :custom-face
+;; (dashboard-heading ((t (:inherit (font-lock-string-face bold)))))
+;; (dashboard-banner ((t (:inherit default))))
+;; :hook
+;; (dashboard-mode . (lambda ()
+;; ;; Enable `page-break-lines-mode'
+;; (when (fboundp 'page-break-lines-mode)
+;; (page-break-lines-mode 1))))
+;; :init
+;; ;; (setq dashboard-items '((recents . 4)
+;; ;; (projects . 3)
+;; ;; (bookmarks . 5))
+;; (setq dashboard-show-shortcuts t
+;; dashboard-center-content nil
+;; ;; dashboard-startup-banner 'logo
+;; dashboard-startup-banner (concat doom-user-dir "splashes/gnu/trancendent-gnu-medium.xpm")
+;; dashboard-banner-logo-title "Welcome Back to Emacs!"
+;; dashboard-page-separator "\n\f\n"
+;; dashboard-display-icons-p t
+;; dashboard-set-file-icons t
+;; dashboard-set-heading-icons t
+;; dashboard-set-navigator t)
+;; ;; Format: "(icon title help action face prefix suffix)"
+;; ;; (setq dashboard-navigator-buttons
+;; ;; `(;; line 1
+;; ;; ((,(nerd-icons-faicon "nf-fa-github" :height 1.0 :v-adjust 0.0)
+;; ;; "GitHub"
+;; ;; "Browse GitHub"
+;; ;; (lambda (&rest _) (browse-url "https://github.com/michaelneuper"))))
+;; ;; (;; line 2
+;; ;; (,(nerd-icons-faicon "nf-fa-calendar" :height 1.0 :v-adjust 0.0)
+;; ;; "Agenda"
+;; ;; "View org-agenda"
+;; ;; (lambda (&rest _) (org-agenda-list)) warning)
+;; ;; (,(nerd-icons-faicon "nf-fa-book" :height 1.0 :v-adjust 0.0)
+;; ;; "Docs"
+;; ;; "Show documentation"
+;; ;; (lambda (&rest _) (doom/help)) warning))))
+;; :config
+;; (dashboard-setup-startup-hook))
+
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/elpa"))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/.local/etc/workspaces/autosave(file-truename "))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/bookmarks"))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/recentf"))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/ido.last"))
+;; (add-to-list 'recentf-exclude (file-truename "~/.cache/treemacs-persist"))
+
+(when (eq system-type 'gnu/linux)
+ (use-package! nyan-mode
+ :init
+ (nyan-mode 1)
+ :config
+ (setq nyan-animate-nyancat t
+ nyan-wavy-trail t)))
+
+(after! doom-modeline
+ (setq doom-modeline-enable-word-count nil
+ doom-modeline-persp-name t
+ doom-modeline-persp-icon t
+ doom-modeline-major-mode-icon t))
+
+(after! centaur-tabs
+ :ensure t
+ :config
+ (setq centaur-tabs-style "bar"
+ centaur-tabs-set-bar 'left
+ centaur-tabs-height 32
+ centaur-tabs-set-icons t
+ centaur-tabs-gray-out-icons 'buffer)
+ (centaur-tabs-headline-match)
+ (centaur-tabs-mode t)
+ (centaur-tabs-group-by-projectile-project))
+
+;; (require 'svg-tag-mode)
+
+;; (defconst date-re "[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}")
+;; (defconst time-re "[0-9]\\{2\\}:[0-9]\\{2\\}")
+;; (defconst day-re "[A-Za-z]\\{3\\}")
+;; (defconst day-time-re (format "\\(%s\\)? ?\\(%s\\)?" day-re time-re))
+
+;; (defun svg-progress-percent (value)
+;; (svg-image (svg-lib-concat
+;; (svg-lib-progress-bar (/ (string-to-number value) 100.0)
+;; nil :margin 0 :stroke 2 :radius 3 :padding 2 :width 11)
+;; (svg-lib-tag (concat value "%")
+;; nil :stroke 0 :margin 0)) :ascent 'center))
+
+;; (defun svg-progress-count (value)
+;; (let* ((seq (mapcar #'string-to-number (split-string value "/")))
+;; (count (float (car seq)))
+;; (total (float (cadr seq))))
+;; (svg-image (svg-lib-concat
+;; (svg-lib-progress-bar (/ count total) nil
+;; :margin 0 :stroke 2 :radius 3 :padding 2 :width 11)
+;; (svg-lib-tag value nil
+;; :stroke 0 :margin 0)) :ascent 'center)))
+
+;; (setq svg-tag-tags
+;; `(
+;; ;; Org tags :TAG1:TAG2:TAG3:
+;; (":\\([A-Za-z0-9]+\\)" . ((lambda (tag) (svg-tag-make tag))))
+;; (":\\([A-Za-z0-9]+[ \-]\\)" . ((lambda (tag) tag)))
+
+;; ;; Org tags #+author
+;; ("#\+\\([A-Za-z0-9]+\\)" . ((lambda (tag) (svg-tag-make tag))))
+;; ("#\+\\([A-Za-z0-9]+[ \-]\\)" . ((lambda (tag) tag)))
+
+;; ;; Task priority [#A] [#B] [#C]
+;; ("\\[#[A-Z]\\]" . ( (lambda (tag)
+;; (svg-tag-make tag :face 'org-priority
+;; :beg 2 :end -1 :margin 0))))
+
+;; ;; Progress [1/3]
+;; ("\\(\\[[0-9]\\{1,3\\}%\\]\\)" . ((lambda (tag)
+;; (svg-progress-percent (substring tag 1 -2)))))
+;; ("\\(\\[[0-9]+/[0-9]+\\]\\)" . ((lambda (tag)
+;; (svg-progress-count (substring tag 1 -1)))))
+
+;; ;; TODO / DONE
+;; ("TODO" . ((lambda (tag) (svg-tag-make "TODO" :face 'org-todo :inverse t :margin 0))))
+;; ("DONE" . ((lambda (tag) (svg-tag-make "DONE" :face 'org-done :margin 0))))
+
+;; ;; Citation of the form [cite:@Knuth:1984]
+;; ("\\(\\[cite:@[A-Za-z]+:\\)" . ((lambda (tag)
+;; (svg-tag-make tag
+;; :inverse t
+;; :beg 7 :end -1
+;; :crop-right t))))
+;; ("\\[cite:@[A-Za-z]+:\\([0-9]+\\]\\)" . ((lambda (tag)
+;; (svg-tag-make tag
+;; :end -1
+;; :crop-left t))))
+
+
+;; ;; Active date (with or without day name, with or without time) <2021-12-24 Fri 14:00>
+;; (,(format "\\(<%s>\\)" date-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :end -1 :margin 0))))
+;; (,(format "\\(<%s \\)%s>" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :inverse nil :crop-right t :margin 0))))
+;; (,(format "<%s \\(%s>\\)" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :end -1 :inverse t :crop-left t :margin 0))))
+
+;; ;; Inactive date (with or without day name, with or without time) [2021-12-24 Fri 14:00]
+;; (,(format "\\(\\[%s\\]\\)" date-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :end -1 :margin 0 :face 'org-date))))
+;; (,(format "\\(\\[%s \\)%s\\]" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :inverse nil :crop-right t :margin 0 :face 'org-date))))
+;; (,(format "\\[%s \\(%s\\]\\)" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :end -1 :inverse t :crop-left t :margin 0 :face 'org-date))))))
+
+;; (add-hook! 'org-mode-hook '(svg-tag-mode t))
+
+(setq undo-limit 80000000)
+
+(setq evil-want-fine-undo t)
+
+;; (defun my-set-evil-insert-state-cursor ()
+;; (unless (derived-mode-p 'eshell-mode)
+;; (setq evil-insert-state-cursor 'box)))
+
+;; (add-hook 'post-command-hook 'my-set-evil-insert-state-cursor)
+
+(after! dirvish
+ (setq! dirvish-quick-access-entries
+ `(("h" "~/" "Home")
+ ("e" ,doom-user-dir "Doom config")
+ ("c" "~/Developer/" "Code")
+ ("d" "~/Downloads/" "Downloads")
+ ("g" "~/GitHub/" "GitHub")
+ ("t" "~/.Trash/" "Trash"))))
+
+(use-package! lsp-mode
+ :init
+ (setq lsp-enable-symbol-highlighting nil
+ lsp-lens-enable nil
+ lsp-headerline-breadcrumb-enable nil
+ lsp-modeline-code-actions-enable t
+ lsp-diagnostics-provider :flycheck
+ lsp-completion-show-detail t
+ lsp-completion-show-kind t))
+
+(use-package! lsp-ui
+ :init
+ (setq lsp-ui-doc-enable nil
+ lsp-ui-sideline-enable nil))
+
+(add-hook 'after-init-hook 'global-company-mode)
+;; from modules/completion/company/config.el
+(use-package! company
+ :commands (company-mode global-company-mode company-complete
+ company-complete-common company-manual-begin company-grab-line)
+ :config
+ (setq company-idle-delay nil
+ company-tooltip-limit 10
+ company-dabbrev-downcase nil
+ company-dabbrev-ignore-case nil)
+ [...])
+
+(map! "M-RET" #'company-manual-begin)
+
+(setq eshell-rc-script (concat doom-user-dir "eshell/profile")
+ eshell-aliases-file (concat doom-user-dir "eshell/aliases")
+ eshell-history-size 5000
+ eshell-buffer-maximum-lines 5000
+ eshell-hist-ignoredups t
+ eshell-scroll-to-bottom-on-input t
+ eshell-destroy-buffer-when-process-dies t
+ eshell-visual-commands'("fish" "htop" "ssh" "top" "zsh"))
+
+(after! (evil copilot)
+ ;; Define the custom function that either accepts the completion or does the default behavior
+ (defun my/copilot-tab-or-default ()
+ (interactive)
+ (if (and (bound-and-true-p copilot-mode)
+ ;; Add any other conditions to check for active copilot suggestions if necessary
+ )
+ (copilot-accept-completion)
+ (evil-insert 1))) ; Default action to insert a tab. Adjust as needed.
+
+ ;; Bind the custom function to <tab> in Evil's insert state
+ (evil-define-key 'insert 'global (kbd "<tab>") 'my/copilot-tab-or-default))
+
+;; (require 'company-tabnine)
+;; (add-to-list 'company-backends #'company-tabnine)
+
+;; (setq company-idle-delay 0
+;; company-show-numbers t)
+
+(add-hook! 'latex-mode-hook
+ (setq TeX-engine 'xetex) 99)
+
+(setq TeX-auto-save t
+ TeX-parse-self t)
+(setq-default TeX-master nil)
+
+(setq +latex-viewers '(pdf-tools zathura))
+
+(setq auto-revert-interval 0.5)
+
+(map! :map cdlatex-mode-map
+ :i "TAB" #'cdlatex-tab)
+
+(map! :after latex
+ :map cdlatex-mode-map
+ :localleader
+ :desc "Insert math symbol"
+ "i" #'cdlatex-math-symbol
+ :desc "Begin environment"
+ "e" #'cdlatex-environment)
+
+;; (load! lazytab.el)
+
+(map! :leader
+ (:prefix ("e" . "evaluate")
+ :desc "Evaluate elisp in buffer"
+ "b" #'eval-buffer
+ :desc "Evaluate defun"
+ "d" #'eval-defun
+ :desc "Evaluate elisp expression"
+ "e" #'eval-expression
+ :desc "Evaluate last sexpression"
+ "l" #'eval-last-sexp
+ :desc "Evaluate elisp in region"
+ "r" #'eval-region))
+
+(after! lsp-mode (require 'lsp-java))
+
+(after! lsp-java
+ (add-hook 'java-mode-hook #'lsp)
+ (add-hook 'java-mode-hook
+ (lambda ()
+ (setq c-basic-offset 4
+ tab-width 4
+ indent-tabs-mode nil))))
+
+(map! :after lsp-java
+ :map java-mode-map
+ :localleader
+ :desc "Add missings imports"
+ "i" #'lsp-java-add-import
+ :desc "Organize imports"
+ "o" #'lsp-java-organize-imports
+ :desc "Build project"
+ "b" #'lsp-java-build-project
+ :desc "Add toString()"
+ "t" #'lsp-java-generate-to-string
+ :desc "Generate getters and setters"
+ "g" #'lsp-java-generate-getters-and-setters
+ :desc "Extract to method"
+ "m" #'lsp-java-extract-method
+ :desc "Extract to constant"
+ "c" #'lsp-java-extract-to-constant
+ :desc "Extract to local variable"
+ "v" #'lsp-java-extract-to-local-variable)
+
+(after! text-mode
+ (add-hook! 'text-mode-hook
+ (unless (derived-mode-p 'org-mode)
+ (with-silent-modifications
+ (ansi-color-apply-on-region (point-min) (point-max) t)))))
+
+(use-package! lsp-pyright
+:ensure t
+:hook (python-mode . (lambda ()
+ (require 'lsp-pyright)
+ (lsp-deferred)))) ; or lsp-deferred
+
+(add-hook! python-mode
+ (setq lsp-pyright-python-executable-cmd "/opt/homebrew/bin/python3.8"
+ python-shell-interpreter "python3.8"
+ doom-modeline-env-python-executable "python3.8"))
+
+(setq org-directory "~/Documents/Org"
+ org-use-property-inheritance t ; fix weird issue with src blocks
+ org-startup-with-inline-images t)
+;; org-startup-with-latex-preview t)
+
+(after! org
+ (setq display-line-numbers-mode 'visual))
+ ;; (org-sticky-header-mode))
+
+(when IS-MAC
+ (use-package! org-mac-link
+ :after org
+ :config
+ (setq org-mac-grab-Acrobat-app-p nil ; disable grabbing from Adobe Acrobat
+ org-mac-grab-devonthink-app-p nil) ; disable grabbinb from DevonThink
+ (map! :map org-mode-map
+ :leader
+ (:prefix "o"
+ :desc "Grab mac link"
+ "g" #'org-mac-grab-link))))
+
+(require 'org)
+(add-to-list 'org-latex-packages-alist '("" "amsmath" t))
+(add-to-list 'org-latex-packages-alist '("" "amssymb" t))
+(add-to-list 'org-latex-packages-alist '("" "mathtools" t))
+(add-to-list 'org-latex-packages-alist '("" "mathrsfs" t))
+(setq org-preview-latex-default-process 'dvisvgm
+ org-format-latex-options (plist-put org-format-latex-options :scale 2.0))
+
+;; xenops
+(add-hook 'org-mode-hook #'xenops-mode)
+(setq xenops-math-image-scale-factor 1.7
+ xenops-reveal-on-entry t)
+
+(defun mn/text-scale-adjust-latex-previews ()
+ "Adjust the size of latex preview fragments when changing the
+buffer's text scale."
+ (pcase major-mode
+ ('latex-mode
+ (dolist (ov (overlays-in (point-min) (point-max)))
+ (if (eq (overlay-get ov 'category)
+ 'preview-overlay)
+ (mn/text-scale--resize-fragment ov))))
+ ('org-mode
+ (dolist (ov (overlays-in (point-min) (point-max)))
+ (if (eq (overlay-get ov 'org-overlay-type)
+ 'org-latex-overlay)
+ (mn/text-scale--resize-fragment ov))))))
+
+(defun mn/text-scale--resize-fragment (ov)
+ (overlay-put
+ ov 'display
+ (cons 'image
+ (plist-put
+ (cdr (overlay-get ov 'display))
+ :scale (+ 1.0 (* 0.25 text-scale-mode-amount))))))
+
+(add-hook 'text-scale-mode-hook #'mn/text-scale-adjust-latex-previews)
+
+(after! org
+ (setq org-agenda-files
+ '("~/Documents/Org/" "~/Documents/Agenda/" "~/Notes/")))
+
+;; (add-to-list 'org-src-lang-modes '("mathematica" . wolfram))
+(autoload 'wolfram-mode "wolfram-mode" nil t) (autoload 'run-wolfram "wolfram-mode" nil t) (setq wolfram-program "/Applications/Mathematica.app/Contents/MacOS/MathKernel")
+(add-to-list 'auto-mode-alist '("\.m$" . wolfram-mode)) (setq wolfram-path "/Users/michael/Library/Mathematica/Kernel")
+;; Load mathematica from contrib
+(org-babel-do-load-languages 'org-babel-load-languages
+ (append org-babel-load-languages
+ '((mathematica . t))
+ ))
+;; Sanitize output and deal with paths
+(setq org-babel-mathematica-command "~/.local/bin/mash.pl")
+;; Font-locking
+(add-to-list 'org-src-lang-modes '("mathematica" . wolfram))
+;; For wolfram-mode
+(setq mathematica-command-line "~/.local/bin/mash.pl")
+
+(defun mn/babel-ansi ()
+ (when-let ((beg (org-babel-where-is-src-block-result nil nil)))
+ (save-excursion
+ (goto-char beg)
+ (when (looking-at org-babel-result-regexp)
+ (let ((end (org-babel-result-end))
+ (ansi-color-context-region nil))
+ (ansi-color-apply-on-region beg end))))))
+
+(add-hook 'org-babel-after-execute-hook 'mn/babel-ansi)
+
+(setq org-feed-alist
+ '(("Michael's Feed"
+ "https://michaelneuper.com/index.xml"
+ "~/Documents/Org/feeds.org" "Michael's Entries")))
+
+(use-package! org-roam
+ :ensure t
+ :config
+ ;; Settings
+ (setq org-roam-directory (file-truename "~/Notes")
+ org-attach-id-dir "assets/")
+ (org-roam-db-autosync-enable)
+ ;; Keybindings
+ (map! :map org-mode-map
+ :leader
+ (:prefix ("r")
+ :desc "Insert node"
+ "i" #'org-roam-node-insert
+ :desc "Find node"
+ "f" #'org-roam-node-find
+ :desc "Capture to node"
+ "c" #'org-roam-capture
+ :desc "Toggle roam buffer"
+ "b" #'org-roam-buffer-toggle
+ :desc "Open random note"
+ "r" #'org-roam-node-random
+ :desc "Visit node"
+ "v" #'org-roam-node-visit))
+ (map! :leader ; unbind default doom binding
+ "n r n" nil))
+ ;; Capture templates
+ ;; (org-roam-capture-templates
+ ;; '(("d" "default" plain
+ ;; "%?"
+ ;; :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
+ ;; :unnarrowed t)
+ ;; ("m" "math" plain
+ ;; "%?"
+ ;; :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+startup: latexpreview\n")
+ ;; :unnarrowed t))))
+
+(use-package! websocket
+ :after org-roam)
+
+(use-package! org-roam-ui
+ :after org-roam ;; or :after org
+ ;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
+ ;; a hookable mode anymore, you're advised to pick something yourself
+ ;; if you don't care about startup time, use
+ ;; :hook (after-init . org-roam-ui-mode)
+ :config
+ ;; Settings
+ (setq org-roam-ui-sync-theme t
+ org-roam-ui-follow t
+ org-roam-ui-update-on-save t
+ org-roam-ui-open-on-start t)
+ ;; Keybindings
+ (map! :leader
+ (:prefix "r"
+ :desc "Open UI"
+ "u" #'org-roam-ui-open)))
+
+;; (setq org-logseq-dir "")
+
+(use-package ox-hugo
+ :ensure t
+ :pin melpa
+ :after ox)
+
+(use-package blog
+ :commands (blog-publish-file
+ blog-generate-file-name
+ blog-read-list-items)
+ :preface
+ (defvar blog-capture-template
+ "#+hugo_base_dir: ../
+#+hugo_section: posts
+#+hugo_auto_set_lastmod: t
+#+options: tex:dvisvgm
+#+macro: kbd @@html:<kbd>$1</kbd>@@
+
+#+title: %(format \"%s\" blog--current-post-name)
+#+date: %(format-time-string \"%Y-%m-%d %h %H:%M\")
+#+hugo_tags: %(blog-read-list-items \"Select tags: \" 'blog-tags)
+#+hugo_categories: %(blog-read-list-items \"Select categories: \" 'blog-categories)
+#+hugo_custom_front_matter: :license %(format \"%S\" blog-license)
+
+%?"
+ "Org-capture template for blog posts.")
+ (defcustom blog-tags nil
+ "A list of tags used for posts."
+ :type '(repeat string)
+ :group 'blog)
+ (defcustom blog-categories nil
+ "A list of tags used for posts."
+ :type '(repeat string)
+ :group 'blog)
+ (defcustom blog-directory "~/blog"
+ "Location of the blog directory for org-capture."
+ :type 'string
+ :group 'blog)
+ (defcustom blog-license ""
+ "Blog license string."
+ :type 'string
+ :group 'blog)
+ (defvar blog--current-post-name nil
+ "Current post name for org-capture template.")
+ (defun blog-read-list-items (prompt var)
+ "Completing read items with the PROMPT from the VAR.
+
+VAR must be a quoted custom variable, which will be saved if new
+items were read by the `completing-read' function."
+ (let ((items (eval var)) item result)
+ (while (not (string-empty-p item))
+ (setq item (string-trim (or (completing-read prompt items) "")))
+ (unless (string-empty-p item)
+ (push item result)
+ (setq items (remove item items))
+ (unless (member item (eval var))
+ (customize-save-variable var (sort (cons item (eval var)) #'string<)))))
+ (string-join result " ")))
+ (defun blog-title-to-fname (title)
+ (thread-last
+ title
+ (replace-regexp-in-string "[[:space:]]" "-")
+ (replace-regexp-in-string "-+" "-")
+ (replace-regexp-in-string "[^[:alnum:]-]+" "")
+ downcase))
+ (defun blog-generate-file-name (&rest _)
+ (let ((title (read-string "Title: ")))
+ (setq blog--current-post-name title)
+ (find-file
+ (file-name-concat
+ (expand-file-name blog-directory)
+ "posts"
+ (format "%s-%s.org"
+ (format-time-string "%Y-%m-%d")
+ (blog-title-to-fname title))))))
+ (defun blog-publish-file ()
+ "Update '#+date:' tag, and rename the currently visited file.
+File name is updated to include the same date and current title."
+ (interactive)
+ (save-match-data
+ (let ((today (format-time-string "%Y-%m-%d"))
+ (now (format-time-string "%h %H:%M")))
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "^#\\+date:.*$")
+ (replace-match (format "#+date: %s %s" today now)))
+ (let* ((file-name (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "^#\\+title:[[:space:]]*\\(.*\\)$")
+ (blog-title-to-fname (match-string 1)))))
+ (condition-case nil
+ (rename-visited-file
+ (format "%s-%s.org" today
+ (if (string-match
+ "^[[:digit:]]\\{4\\}-[[:digit:]]\\{2\\}-[[:digit:]]\\{2\\}-\\(.*\\)$"
+ file-name)
+ (match-string 1 file-name)
+ file-name)))
+ (file-already-exists nil))
+ (save-buffer)))))
+ (provide 'blog))
+
+(use-package! smudge
+ :init
+ (setq smudge-status-location 'modeline
+ smudge-transport 'connect) ; requires spotify premium
+ :config
+ ;; General keybindings
+ (map! :leader
+ (:prefix ("m" . "music")
+ :desc "Toggle shuffle"
+ "s" #'smudge-controller-toggle-shuffle
+ :desc "Toggle repeat"
+ "r" #'smudge-controller-toggle-repeat
+ :desc "Play/pause"
+ "SPC" #'smudge-controller-toggle-play
+ :desc "Next track"
+ "f" #'smudge-controller-next-track
+ :desc "Next track"
+ "n" #'smudge-controller-next-track
+ :desc "Previous track"
+ "b" #'smudge-controller-previous-track
+ :desc "My playlists"
+ "m" #'smudge-my-playlists
+ :desc "Select playback device"))
+ ;; Playlist keybindings
+ (map! :leader
+ (:prefix ("m p" . "playlists")
+ :desc "Featured playlists"
+ "f" #'smudge-featured-playlists
+ :desc "Search playlists"
+ "s" #'smudge-playlist-search
+ :desc "Show user's playlists"
+ "u" #'smudge-user-playlists
+ :desc "Create new playlist"
+ "c" #'smudge-create-playlist))
+ ;; Track keybindings
+ (map! :leader
+ (:prefix ("m t" . "tracks")
+ :desc "List recently played tracks"
+ "r" #'smudge-recently-played
+ :desc "Search for trakcs"
+ "s" #'smudge-track-search))
+ ;; Volume keybindings
+ (map! :leader
+ (:prefix ("m v" . "volume")
+ :desc "Increase volume"
+ "u" #'smudge-controller-volume-up
+ :desc "Decrease volume"
+ "d" #'smudge-controller-volume-down
+ :desc "Toggle mute"
+ "m" #'smudge-controller-voume-mute-unmute)))
+
+(use-package calibredb
+ :defer t
+ :config
+ (setq calibredb-root-dir "~/Books"
+ calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir)
+ calibredb-library-alist '(("~/Books"))))
+
+(setq calc-angle-mode 'rad
+ calc-complex-format 'i
+ calc-prefer-frac t)
diff --git a/config.org b/config.org
@@ -0,0 +1,1191 @@
+#+title: Doom Emacs Config
+#+author: Michael Neuper
+
+* Doom
+#+begin_src emacs-lisp
+;; Whenever you reconfigure a package, make sure to wrap your config in an
+;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
+
+;; (after! PACKAGE
+;; (setq x y))
+
+;; The exceptions to this rule:
+;; - Setting file/directory variables (like `org-directory')
+;; - Setting variables which explicitly tell you to set them before their
+;; package is loaded (see 'C-h v VARIABLE' to look up their documentation).
+;; - Setting doom variables (which start with 'doom-' or '+').
+
+;; Here are some additional functions/macros that will help you configure Doom.
+
+;; - `load!' for loading external *.el files relative to this one
+;; - `use-package!' for configuring packages
+;; - `after!' for running code after a package has loaded
+;; - `add-load-path!' for adding directories to the `load-path', relative to
+;; this file. Emacs searches the `load-path' when you load packages with
+;; `require' or `use-package'.
+;; - `map!' for binding new keys
+
+;; To get information about any of these functions/macros, move the cursor over
+;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
+;; This will open documentation for it, including demos of how they are used.
+;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
+;; etc).
+
+;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
+;; they are implemented.
+#+end_src
+
+Make emacs faster
+#+begin_src emacs-lisp
+(use-package! gcmh
+ :init
+ (setq gcmh-idle-delay 5
+ gcmh-high-cons-threshold (* 256 1024 1024)) ; 256MB during idle
+ :config
+ (gcmh-mode 1))
+
+(setq gc-cons-threshold 200000000) ; previous 33554432
+#+end_src
+
+* Configuration
+** Local Leader Key
+Remap <localleader> from m to l to avoid conflict with spotify bindings.
+
+#+begin_src emacs-lisp
+(setq doom-localleader-key "SPC l"
+ doom-localleader-alt-key "M-SPC l")
+#+end_src
+
+** Auto-Save and Backup
+#+begin_src emacs-lisp
+(setq auto-save-default t
+ make-backup-files t)
+#+end_src
+
+** Confirm Kill Emacs
+Kill emacs without confirming.
+
+#+begin_src emacs-lisp
+(setq confirm-kill-emacs nil)
+#+end_src
+
+** Credentials
+#+begin_src emacs-lisp
+(setq user-full-name "Michael Neuper"
+ user-mail-address "michael@michaelneuper.com")
+#+end_src
+
+** API Keys
+Import API keys used for various programs.
+
+#+begin_src emacs-lisp
+(load! "api-keys.el")
+#+end_src
+
+** MacOS Specific
+Set modifier keys.
+#+begin_src emacs-lisp
+(when IS-MAC
+ (setq mac-command-modifier 'meta
+ mac-option-modifier 'super
+ mac-right-option-modifier 'none))
+#+end_src
+
+Fix using keychain.
+#+begin_src emacs-lisp
+(after! auth-source
+ (setq auth-sources (nreverse auth-sources)))
+#+end_src
+
+Titlebar.
+#+begin_src emacs-lisp
+(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
+(add-to-list 'default-frame-alist '(ns-appearance . dark))
+#+end_src
+
+** Keybindings
+#+begin_src emacs-lisp
+(map! :leader
+ (:prefix "t"
+ :desc "Calc"
+ "c" #'calc
+ :desc "Eshell"
+ "e" #'+eshell/toggle
+ :desc "Scroll bar"
+ "s" #'scroll-bar-mode
+ :desc "Vterm"
+ "v" #'+vterm/toggle))
+
+(global-set-key (kbd "<f4>") #'deadgrep)
+(global-set-key (kbd "<f3>") #'ibuffer)
+#+end_src
+
+* Window Management
+** Split Window Behaviour
+Focus split window.
+#+begin_src emacs-lisp
+(setq evil-split-window-below t
+ evil-vsplit-window-right t)
+#+end_src
+
+** Prompt for Buffers
+Ask what buffer to switch to when doing a split.
+#+begin_src emacs-lisp
+(defadvice! prompt-for-buffers (&rest _)
+ :after '(evil-window-split evil-window-vsplit)
+ (consult-buffer))
+#+end_src
+
+* Interface
+** Basic
+*** UI Elements
+#+begin_src emacs-lisp
+;; (scroll-bar-mode 1)
+;; (blink-cursor-mode 1)
+
+;; mac specific
+(when IS-MAC
+ (display-battery-mode 1))
+#+end_src
+
+*** Theme
+Use doom-one theme.
+#+begin_src emacs-lisp
+(setq doom-theme 'doom-gruvbox)
+#+end_src
+
+Other good looking themes (ranked):
+- doom-one
+- doom-snazzy
+- doom-dark+
+- doom-xcode
+- doom-material
+
+*** Faces
+#+begin_src emacs-lisp
+;; (custom-set-faces!
+;; '(doom-dashboard-banner :inherit default)
+;; '(doom-dashboard-loaded :inherit default)
+;; '(dashboard-banner :inherrit default))
+
+;; (custom-set-faces!
+;; '(dashboard-startup-banner :inherit default))
+#+end_src
+
+*** Line Numbers
+Enable relative line numbers.
+Number them relatively (better view with folded org headings).
+
+#+begin_src emacs-lisp
+(setq display-line-numbers-type 'relative)
+(setq display-line-numbers-mode 'visual)
+(setq display-line-numbers 'visual)
+#+end_src
+
+*** Column Indicator
+Display column indicator after 80 characters in programming mode.
+
+#+begin_src emacs-lisp
+(setq display-fill-column-indicator-column 80)
+(add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)
+#+end_src
+
+*** Pixel Scroll
+Enable pixel precision scrolling.
+
+#+begin_src emacs-lisp
+(when (version< "29.0.50" emacs-version)
+ (pixel-scroll-precision-mode 1))
+#+end_src
+
+*** Fonts
+Set doom fonts.
+
+Best looking fonts:
+ - JetBrains Mono
+ - Cascadia Code
+ - Comic Shanns Mono
+ - Code New Roman
+ - Fira Code
+ - Inconsolata
+
+#+begin_src emacs-lisp
+(cond (IS-LINUX
+ (setq doom-font (font-spec :family "Fira Code" :size 12.5)
+ doom-variable-pitch-font (font-spec :family "Noto Sans" :size 15)))
+ (IS-MAC
+ (setq doom-font (font-spec :family "JetBrainsMono Nerd Font" :size 15.5))
+ (setq doom-symbol-font (font-spec :family "Cascadia Code" :size 15.5))))
+#+end_src
+
+Italicize comments.
+
+#+begin_src emacs-lisp
+(after! doom-themes
+ (setq doom-themes-enable-bold t))
+ ;; doom-themes-enable-italic t))
+
+;; (custom-set-faces!
+;; '(font-lock-comment-face :slant italic)
+;; '(font-lock-keyword-face :slant italic))
+#+end_src
+
+Disable certain ligatures.
+
+#+begin_src emacs-lisp
+;; (plist-put! +ligatures-extra-symbols
+;; :and nil
+;; :or nil
+;; :not nil
+;; :true nil
+;; :false nil
+;; :int nil
+;; :float nil
+;; :str nil
+;; :bool nil
+;; :list nil)
+#+end_src
+
+Enable certain ligatures.
+
+#+begin_src emacs-lisp
+(after! org
+ (setq org-ellipsis " ▾ ")
+ ;; (appendq! +ligatures-extra-symbols
+ ;; `(:checkbox "☐"
+ ;; :pending "◼"
+ ;; :checkedbox "☑"
+ ;; :list_property "∷"
+ ;; :em_dash "—"
+ ;; :ellipses "…"
+ ;; :arrow_right "→"
+ ;; :arrow_left "←"
+ ;; :begin_quote "❝"
+ ;; :end_quote "❞"
+ ;; :header "›"
+ ;; :priority_a ,(propertize "⚑" 'face 'all-the-icons-red)
+ ;; :priority_b ,(propertize "⬆" 'face 'all-the-icons-orange)
+ ;; :priority_c ,(propertize "■" 'face 'all-the-icons-yellow)
+ ;; :priority_d ,(propertize "⬇" 'face 'all-the-icons-green)
+ ;; :priority_e ,(propertize "❓" 'face 'all-the-icons-blue)
+ ;; :roam_tags nil
+ ;; :filetags nil))
+ (set-ligatures! 'org-mode
+ :merge t
+ :checkbox "[ ]"
+ :pending "[-]"
+ :checkedbox "[X]"
+ :list_property "::"
+ :em_dash "---"
+ :ellipsis "..."
+ :arrow_right "->"
+ :arrow_left "<-"
+ :title "#+title:"
+ :subtitle "#+subtitle:"
+ :author "#+author:"
+ :date "#+date:"
+ :property "#+property:"
+ :options "#+options:"
+ :startup "#+startup:"
+ :macro "#+macro:"
+ :html_head "#+html_head:"
+ :html "#+html:"
+ :latex_class "#+latex_class:"
+ :latex_header "#+latex_header:"
+ :beamer_header "#+beamer_header:"
+ :latex "#+latex:"
+ :attr_latex "#+attr_latex:"
+ :attr_html "#+attr_html:"
+ :attr_org "#+attr_org:"
+ :begin_quote "#+begin_quote"
+ :end_quote "#+end_quote"
+ :caption "#+caption:"
+ :header "#+header:"
+ :begin_export "#+begin_export"
+ :end_export "#+end_export"
+ :results "#+RESULTS:"
+ :property ":PROPERTIES:"
+ :end ":END:"
+ :priority_a "[#A]"
+ :priority_b "[#B]"
+ :priority_c "[#C]"
+ :priority_d "[#D]"
+ :priority_e "[#E]"
+ :roam_tags "#+roam_tags:"
+ :filetags "#+filetags:")
+ (plist-put +ligatures-extra-symbols :name "⁍"))
+#+end_src
+
+*** Info-Colors
+#+begin_src emacs-lisp
+(use-package! info-colors
+ :commands (info-colors-fontify-node))
+
+(add-hook 'Info-selection-hook
+ 'info-colors-fontify-node)
+#+end_src
+
+** Dashboard
+*** doom-dashboard
+Remove menus.
+#+begin_src emacs-lisp
+(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu)
+
+
+(add-hook! '+doom-dashboard-functions :append
+ (insert "\n" (+doom-dashboard--center +doom-dashboard--width "Welcome back to Emacs!"))
+ (setq mode-line-format nil)
+ (hl-line-mode 0)
+ (read-only-mode +1))
+
+(setq-hook! '+doom-dashboard-mode-hook evil-normal-state-cursor (list nil))
+#+end_src
+
+Custom ASCII banner.
+#+begin_src emacs-lisp
+(defun my-weebery-is-always-greater ()
+ (let* ((banner '("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀"
+ "⢸⠉⣹⠋⠉⢉⡟⢩⢋⠋⣽⡻⠭⢽⢉⠯⠭⠭⠭⢽⡍⢹⡍⠙⣯⠉⠉⠉⠉⠉⣿⢫⠉⠉⠉⢉⡟⠉⢿⢹⠉⢉⣉⢿⡝⡉⢩⢿⣻⢍⠉⠉⠩⢹⣟⡏⠉⠹⡉⢻⡍⡇"
+ "⢸⢠⢹⠀⠀⢸⠁⣼⠀⣼⡝⠀⠀⢸⠘⠀⠀⠀⠀⠈⢿⠀⡟⡄⠹⣣⠀⠀⠐⠀⢸⡘⡄⣤⠀⡼⠁⠀⢺⡘⠉⠀⠀⠀⠫⣪⣌⡌⢳⡻⣦⠀⠀⢃⡽⡼⡀⠀⢣⢸⠸⡇"
+ "⢸⡸⢸⠀⠀⣿⠀⣇⢠⡿⠀⠀⠀⠸⡇⠀⠀⠀⠀⠀⠘⢇⠸⠘⡀⠻⣇⠀⠀⠄⠀⡇⢣⢛⠀⡇⠀⠀⣸⠇⠀⠀⠀⠀⠀⠘⠄⢻⡀⠻⣻⣧⠀⠀⠃⢧⡇⠀⢸⢸⡇⡇"
+ "⢸⡇⢸⣠⠀⣿⢠⣿⡾⠁⠀⢀⡀⠤⢇⣀⣐⣀⠀⠤⢀⠈⠢⡡⡈⢦⡙⣷⡀⠀⠀⢿⠈⢻⣡⠁⠀⢀⠏⠀⠀⠀⢀⠀⠄⣀⣐⣀⣙⠢⡌⣻⣷⡀⢹⢸⡅⠀⢸⠸⡇⡇"
+ "⢸⡇⢸⣟⠀⢿⢸⡿⠀⣀⣶⣷⣾⡿⠿⣿⣿⣿⣿⣿⣶⣬⡀⠐⠰⣄⠙⠪⣻⣦⡀⠘⣧⠀⠙⠄⠀⠀⠀⠀⠀⣨⣴⣾⣿⠿⣿⣿⣿⣿⣿⣶⣯⣿⣼⢼⡇⠀⢸⡇⡇⠇"
+ "⢸⢧⠀⣿⡅⢸⣼⡷⣾⣿⡟⠋⣿⠓⢲⣿⣿⣿⡟⠙⣿⠛⢯⡳⡀⠈⠓⠄⡈⠚⠿⣧⣌⢧⠀⠀⠀⠀⠀⣠⣺⠟⢫⡿⠓⢺⣿⣿⣿⠏⠙⣏⠛⣿⣿⣾⡇⢀⡿⢠⠀⡇"
+ "⢸⢸⠀⢹⣷⡀⢿⡁⠀⠻⣇⠀⣇⠀⠘⣿⣿⡿⠁⠐⣉⡀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠉⠓⠳⠄⠀⠀⠀⠀⠋⠀⠘⡇⠀⠸⣿⣿⠟⠀⢈⣉⢠⡿⠁⣼⠁⣼⠃⣼⠀⡇"
+ "⢸⠸⣀⠈⣯⢳⡘⣇⠀⠀⠈⡂⣜⣆⡀⠀⠀⢀⣀⡴⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢽⣆⣀⠀⠀⠀⣀⣜⠕⡊⠀⣸⠇⣼⡟⢠⠏⠀⡇"
+ "⢸⠀⡟⠀⢸⡆⢹⡜⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠋⣾⡏⡇⡎⡇⠀⡇"
+ "⢸⠀⢃⡆⠀⢿⡄⠑⢽⣄⠀⠀⠀⢀⠂⠠⢁⠈⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠄⡐⢀⠂⠀⠀⣠⣮⡟⢹⣯⣸⣱⠁⠀⡇"
+ "⠈⠉⠉⠉⠉⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁"))
+ (longest-line (apply #'max (mapcar #'length banner))))
+ (put-text-property
+ (point)
+ (dolist (line banner (point))
+ (insert (+doom-dashboard--center
+ +doom-dashboard--width
+ (concat line (make-string (max 0 (- longest-line (length line))) 32)))
+ "\n"))
+ 'face 'doom-dashboard-banner)))
+
+(setq +doom-dashboard-ascii-banner-fn #'my-weebery-is-always-greater)
+#+end_src
+
+Image banner.
+#+begin_src emacs-lisp
+;; (setq fancy-splash-image (concat doom-private-dir "splashes/gnu/trancendent-gnu-medium.xpm"))
+#+end_src
+
+*** dashboard
+Switch to dashboard from doom-dashboard.
+#+begin_src emacs-lisp
+;; (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")))
+;; (setq doom-fallback-buffer-name "*dashboard*")
+#+end_src
+
+Configure dashboard
+#+begin_src emacs-lisp
+;; (use-package! dashboard
+;; :custom-face
+;; (dashboard-heading ((t (:inherit (font-lock-string-face bold)))))
+;; (dashboard-banner ((t (:inherit default))))
+;; :hook
+;; (dashboard-mode . (lambda ()
+;; ;; Enable `page-break-lines-mode'
+;; (when (fboundp 'page-break-lines-mode)
+;; (page-break-lines-mode 1))))
+;; :init
+;; ;; (setq dashboard-items '((recents . 4)
+;; ;; (projects . 3)
+;; ;; (bookmarks . 5))
+;; (setq dashboard-show-shortcuts t
+;; dashboard-center-content nil
+;; ;; dashboard-startup-banner 'logo
+;; dashboard-startup-banner (concat doom-user-dir "splashes/gnu/trancendent-gnu-medium.xpm")
+;; dashboard-banner-logo-title "Welcome Back to Emacs!"
+;; dashboard-page-separator "\n\f\n"
+;; dashboard-display-icons-p t
+;; dashboard-set-file-icons t
+;; dashboard-set-heading-icons t
+;; dashboard-set-navigator t)
+;; ;; Format: "(icon title help action face prefix suffix)"
+;; ;; (setq dashboard-navigator-buttons
+;; ;; `(;; line 1
+;; ;; ((,(nerd-icons-faicon "nf-fa-github" :height 1.0 :v-adjust 0.0)
+;; ;; "GitHub"
+;; ;; "Browse GitHub"
+;; ;; (lambda (&rest _) (browse-url "https://github.com/michaelneuper"))))
+;; ;; (;; line 2
+;; ;; (,(nerd-icons-faicon "nf-fa-calendar" :height 1.0 :v-adjust 0.0)
+;; ;; "Agenda"
+;; ;; "View org-agenda"
+;; ;; (lambda (&rest _) (org-agenda-list)) warning)
+;; ;; (,(nerd-icons-faicon "nf-fa-book" :height 1.0 :v-adjust 0.0)
+;; ;; "Docs"
+;; ;; "Show documentation"
+;; ;; (lambda (&rest _) (doom/help)) warning))))
+;; :config
+;; (dashboard-setup-startup-hook))
+#+end_src
+
+Exclude files from showing in recents.
+#+begin_src emacs-lisp
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/elpa"))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/.local/etc/workspaces/autosave(file-truename "))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/bookmarks"))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/recentf"))
+;; (add-to-list 'recentf-exclude (file-truename "~/Repos/dotfiles/.config/emacs/ido.last"))
+;; (add-to-list 'recentf-exclude (file-truename "~/.cache/treemacs-persist"))
+#+end_src
+
+** Modeline
+Enable nyan-cat in modeline.
+
+#+begin_src emacs-lisp
+(when (eq system-type 'gnu/linux)
+ (use-package! nyan-mode
+ :init
+ (nyan-mode 1)
+ :config
+ (setq nyan-animate-nyancat t
+ nyan-wavy-trail t)))
+#+end_src
+
+Enable extra icons in doom-modeline.
+
+#+begin_src emacs-lisp
+(after! doom-modeline
+ (setq doom-modeline-enable-word-count nil
+ doom-modeline-persp-name t
+ doom-modeline-persp-icon t
+ doom-modeline-major-mode-icon t))
+#+end_src
+
+** Tabs
+#+begin_src emacs-lisp
+(after! centaur-tabs
+ :ensure t
+ :config
+ (setq centaur-tabs-style "bar"
+ centaur-tabs-set-bar 'left
+ centaur-tabs-height 32
+ centaur-tabs-set-icons t
+ centaur-tabs-gray-out-icons 'buffer)
+ (centaur-tabs-headline-match)
+ (centaur-tabs-mode t)
+ (centaur-tabs-group-by-projectile-project))
+#+end_src
+
+** TODO SVG Tags
+Enable SVG tags in org mode.
+
+#+begin_src emacs-lisp
+;; (require 'svg-tag-mode)
+
+;; (defconst date-re "[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}")
+;; (defconst time-re "[0-9]\\{2\\}:[0-9]\\{2\\}")
+;; (defconst day-re "[A-Za-z]\\{3\\}")
+;; (defconst day-time-re (format "\\(%s\\)? ?\\(%s\\)?" day-re time-re))
+
+;; (defun svg-progress-percent (value)
+;; (svg-image (svg-lib-concat
+;; (svg-lib-progress-bar (/ (string-to-number value) 100.0)
+;; nil :margin 0 :stroke 2 :radius 3 :padding 2 :width 11)
+;; (svg-lib-tag (concat value "%")
+;; nil :stroke 0 :margin 0)) :ascent 'center))
+
+;; (defun svg-progress-count (value)
+;; (let* ((seq (mapcar #'string-to-number (split-string value "/")))
+;; (count (float (car seq)))
+;; (total (float (cadr seq))))
+;; (svg-image (svg-lib-concat
+;; (svg-lib-progress-bar (/ count total) nil
+;; :margin 0 :stroke 2 :radius 3 :padding 2 :width 11)
+;; (svg-lib-tag value nil
+;; :stroke 0 :margin 0)) :ascent 'center)))
+
+;; (setq svg-tag-tags
+;; `(
+;; ;; Org tags :TAG1:TAG2:TAG3:
+;; (":\\([A-Za-z0-9]+\\)" . ((lambda (tag) (svg-tag-make tag))))
+;; (":\\([A-Za-z0-9]+[ \-]\\)" . ((lambda (tag) tag)))
+
+;; ;; Org tags #+author
+;; ("#\+\\([A-Za-z0-9]+\\)" . ((lambda (tag) (svg-tag-make tag))))
+;; ("#\+\\([A-Za-z0-9]+[ \-]\\)" . ((lambda (tag) tag)))
+
+;; ;; Task priority [#A] [#B] [#C]
+;; ("\\[#[A-Z]\\]" . ( (lambda (tag)
+;; (svg-tag-make tag :face 'org-priority
+;; :beg 2 :end -1 :margin 0))))
+
+;; ;; Progress [1/3]
+;; ("\\(\\[[0-9]\\{1,3\\}%\\]\\)" . ((lambda (tag)
+;; (svg-progress-percent (substring tag 1 -2)))))
+;; ("\\(\\[[0-9]+/[0-9]+\\]\\)" . ((lambda (tag)
+;; (svg-progress-count (substring tag 1 -1)))))
+
+;; ;; TODO / DONE
+;; ("TODO" . ((lambda (tag) (svg-tag-make "TODO" :face 'org-todo :inverse t :margin 0))))
+;; ("DONE" . ((lambda (tag) (svg-tag-make "DONE" :face 'org-done :margin 0))))
+
+;; ;; Citation of the form [cite:@Knuth:1984]
+;; ("\\(\\[cite:@[A-Za-z]+:\\)" . ((lambda (tag)
+;; (svg-tag-make tag
+;; :inverse t
+;; :beg 7 :end -1
+;; :crop-right t))))
+;; ("\\[cite:@[A-Za-z]+:\\([0-9]+\\]\\)" . ((lambda (tag)
+;; (svg-tag-make tag
+;; :end -1
+;; :crop-left t))))
+
+
+;; ;; Active date (with or without day name, with or without time) <2021-12-24 Fri 14:00>
+;; (,(format "\\(<%s>\\)" date-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :end -1 :margin 0))))
+;; (,(format "\\(<%s \\)%s>" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :inverse nil :crop-right t :margin 0))))
+;; (,(format "<%s \\(%s>\\)" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :end -1 :inverse t :crop-left t :margin 0))))
+
+;; ;; Inactive date (with or without day name, with or without time) [2021-12-24 Fri 14:00]
+;; (,(format "\\(\\[%s\\]\\)" date-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :end -1 :margin 0 :face 'org-date))))
+;; (,(format "\\(\\[%s \\)%s\\]" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :beg 1 :inverse nil :crop-right t :margin 0 :face 'org-date))))
+;; (,(format "\\[%s \\(%s\\]\\)" date-re day-time-re) .
+;; ((lambda (tag)
+;; (svg-tag-make tag :end -1 :inverse t :crop-left t :margin 0 :face 'org-date))))))
+
+;; (add-hook! 'org-mode-hook '(svg-tag-mode t))
+#+end_src
+
+* Evil Mode
+Raise undo limit to 80mb.
+
+#+begin_src emacs-lisp
+(setq undo-limit 80000000)
+#+end_src
+
+Grandular changes when in insert mode.
+
+#+begin_src emacs-lisp
+(setq evil-want-fine-undo t)
+#+end_src
+
+Use block cursor in insert mode.
+
+#+begin_src emacs-lisp
+;; (defun my-set-evil-insert-state-cursor ()
+;; (unless (derived-mode-p 'eshell-mode)
+;; (setq evil-insert-state-cursor 'box)))
+
+;; (add-hook 'post-command-hook 'my-set-evil-insert-state-cursor)
+#+end_src
+
+* Dired/Dirvish
+#+begin_src emacs-lisp
+(after! dirvish
+ (setq! dirvish-quick-access-entries
+ `(("h" "~/" "Home")
+ ("e" ,doom-user-dir "Doom config")
+ ("c" "~/Developer/" "Code")
+ ("d" "~/Downloads/" "Downloads")
+ ("g" "~/GitHub/" "GitHub")
+ ("t" "~/.Trash/" "Trash"))))
+#+end_src
+
+* Programming
+** LSP
+#+begin_src emacs-lisp
+(use-package! lsp-mode
+ :init
+ (setq lsp-enable-symbol-highlighting nil
+ lsp-lens-enable nil
+ lsp-headerline-breadcrumb-enable nil
+ lsp-modeline-code-actions-enable t
+ lsp-diagnostics-provider :flycheck
+ lsp-completion-show-detail t
+ lsp-completion-show-kind t))
+
+(use-package! lsp-ui
+ :init
+ (setq lsp-ui-doc-enable nil
+ lsp-ui-sideline-enable nil))
+#+end_src
+
+** Company
+#+begin_src emacs-lisp
+(add-hook 'after-init-hook 'global-company-mode)
+;; from modules/completion/company/config.el
+(use-package! company
+ :commands (company-mode global-company-mode company-complete
+ company-complete-common company-manual-begin company-grab-line)
+ :config
+ (setq company-idle-delay nil
+ company-tooltip-limit 10
+ company-dabbrev-downcase nil
+ company-dabbrev-ignore-case nil)
+ [...])
+
+(map! "M-RET" #'company-manual-begin)
+#+end_src
+
+** Eshell
+#+begin_src emacs-lisp
+(setq eshell-rc-script (concat doom-user-dir "eshell/profile")
+ eshell-aliases-file (concat doom-user-dir "eshell/aliases")
+ eshell-history-size 5000
+ eshell-buffer-maximum-lines 5000
+ eshell-hist-ignoredups t
+ eshell-scroll-to-bottom-on-input t
+ eshell-destroy-buffer-when-process-dies t
+ eshell-visual-commands'("fish" "htop" "ssh" "top" "zsh"))
+#+end_src
+
+** Copilot
+#+begin_src emacs-lisp
+(after! (evil copilot)
+ ;; Define the custom function that either accepts the completion or does the default behavior
+ (defun my/copilot-tab-or-default ()
+ (interactive)
+ (if (and (bound-and-true-p copilot-mode)
+ ;; Add any other conditions to check for active copilot suggestions if necessary
+ )
+ (copilot-accept-completion)
+ (evil-insert 1))) ; Default action to insert a tab. Adjust as needed.
+
+ ;; Bind the custom function to <tab> in Evil's insert state
+ (evil-define-key 'insert 'global (kbd "<tab>") 'my/copilot-tab-or-default))
+#+end_src
+
+** Tabnine
+Enable tabnine.
+
+#+begin_src emacs-lisp
+;; (require 'company-tabnine)
+;; (add-to-list 'company-backends #'company-tabnine)
+#+end_src
+
+Configure tabnine.
+
+#+begin_src emacs-lisp
+;; (setq company-idle-delay 0
+;; company-show-numbers t)
+#+end_src
+
+** Languages
+*** LaTeX
+Change LaTeX compiler to XeLaTeX.
+#+begin_src emacs-lisp
+(add-hook! 'latex-mode-hook
+ (setq TeX-engine 'xetex) 99)
+#+end_src
+
+Make AUCTeX aware of syle files and multi-file documents right away.
+#+begin_src emacs-lisp
+(setq TeX-auto-save t
+ TeX-parse-self t)
+(setq-default TeX-master nil)
+#+end_src
+
+Reorder list of pdf viewers.
+#+begin_src emacs-lisp
+(setq +latex-viewers '(pdf-tools zathura))
+#+end_src
+
+Make pdf-tools automatically update the buffer.
+#+begin_src emacs-lisp
+(setq auto-revert-interval 0.5)
+#+end_src
+
+Use cdlatex completion instead of yasnippet.
+#+begin_src emacs-lisp
+(map! :map cdlatex-mode-map
+ :i "TAB" #'cdlatex-tab)
+#+end_src
+
+CDLaTeX keybindings.
+#+begin_src emacs-lisp
+(map! :after latex
+ :map cdlatex-mode-map
+ :localleader
+ :desc "Insert math symbol"
+ "i" #'cdlatex-math-symbol
+ :desc "Begin environment"
+ "e" #'cdlatex-environment)
+#+end_src
+
+Use lazytab package.
+#+begin_src emacs-lisp
+;; (load! lazytab.el)
+#+end_src
+
+*** Emacs Lisp
+Set elisp evaluate keybindings.
+#+begin_src emacs-lisp
+(map! :leader
+ (:prefix ("e" . "evaluate")
+ :desc "Evaluate elisp in buffer"
+ "b" #'eval-buffer
+ :desc "Evaluate defun"
+ "d" #'eval-defun
+ :desc "Evaluate elisp expression"
+ "e" #'eval-expression
+ :desc "Evaluate last sexpression"
+ "l" #'eval-last-sexp
+ :desc "Evaluate elisp in region"
+ "r" #'eval-region))
+#+end_src
+
+*** Java
+Enable LSP mode for java.
+#+begin_src emacs-lisp
+(after! lsp-mode (require 'lsp-java))
+#+end_src
+
+Configure LSP java.
+#+begin_src emacs-lisp
+(after! lsp-java
+ (add-hook 'java-mode-hook #'lsp)
+ (add-hook 'java-mode-hook
+ (lambda ()
+ (setq c-basic-offset 4
+ tab-width 4
+ indent-tabs-mode nil))))
+#+end_src
+
+Keybindings for java.
+#+begin_src emacs-lisp
+(map! :after lsp-java
+ :map java-mode-map
+ :localleader
+ :desc "Add missings imports"
+ "i" #'lsp-java-add-import
+ :desc "Organize imports"
+ "o" #'lsp-java-organize-imports
+ :desc "Build project"
+ "b" #'lsp-java-build-project
+ :desc "Add toString()"
+ "t" #'lsp-java-generate-to-string
+ :desc "Generate getters and setters"
+ "g" #'lsp-java-generate-getters-and-setters
+ :desc "Extract to method"
+ "m" #'lsp-java-extract-method
+ :desc "Extract to constant"
+ "c" #'lsp-java-extract-to-constant
+ :desc "Extract to local variable"
+ "v" #'lsp-java-extract-to-local-variable)
+#+end_src
+
+Display ansi colour codes in java output.
+#+begin_src emacs-lisp
+(after! text-mode
+ (add-hook! 'text-mode-hook
+ (unless (derived-mode-p 'org-mode)
+ (with-silent-modifications
+ (ansi-color-apply-on-region (point-min) (point-max) t)))))
+#+end_src
+
+*** Python
+Install pyright lsp server
+#+begin_src emacs-lisp
+(use-package! lsp-pyright
+:ensure t
+:hook (python-mode . (lambda ()
+ (require 'lsp-pyright)
+ (lsp-deferred)))) ; or lsp-deferred
+#+end_src
+
+Set python version
+#+begin_src emacs-lisp
+(add-hook! python-mode
+ (setq lsp-pyright-python-executable-cmd "/opt/homebrew/bin/python3.8"
+ python-shell-interpreter "python3.8"
+ doom-modeline-env-python-executable "python3.8"))
+
+#+end_src
+
+* Org
+** Org Mode
+*** View
+Configure org-mode settings.
+
+#+begin_src emacs-lisp
+(setq org-directory "~/Documents/Org"
+ org-use-property-inheritance t ; fix weird issue with src blocks
+ org-startup-with-inline-images t)
+;; org-startup-with-latex-preview t)
+#+end_src
+
+Use visual line numbers to avoid wrong line numbers in folded content.
+
+#+begin_src emacs-lisp
+(after! org
+ (setq display-line-numbers-mode 'visual))
+ ;; (org-sticky-header-mode))
+#+end_src
+
+Grab links from macOS applications.
+
+#+begin_src emacs-lisp
+(when IS-MAC
+ (use-package! org-mac-link
+ :after org
+ :config
+ (setq org-mac-grab-Acrobat-app-p nil ; disable grabbing from Adobe Acrobat
+ org-mac-grab-devonthink-app-p nil) ; disable grabbinb from DevonThink
+ (map! :map org-mode-map
+ :leader
+ (:prefix "o"
+ :desc "Grab mac link"
+ "g" #'org-mac-grab-link))))
+#+end_src
+
+*** Org LaTeX
+#+begin_src emacs-lisp
+(require 'org)
+(add-to-list 'org-latex-packages-alist '("" "amsmath" t))
+(add-to-list 'org-latex-packages-alist '("" "amssymb" t))
+(add-to-list 'org-latex-packages-alist '("" "mathtools" t))
+(add-to-list 'org-latex-packages-alist '("" "mathrsfs" t))
+(setq org-preview-latex-default-process 'dvisvgm
+ org-format-latex-options (plist-put org-format-latex-options :scale 2.0))
+
+;; xenops
+(add-hook 'org-mode-hook #'xenops-mode)
+(setq xenops-math-image-scale-factor 1.7
+ xenops-reveal-on-entry t)
+#+end_src
+
+Scale LaTeX previews when rescaling text.
+
+#+begin_src emacs-lisp
+(defun mn/text-scale-adjust-latex-previews ()
+ "Adjust the size of latex preview fragments when changing the
+buffer's text scale."
+ (pcase major-mode
+ ('latex-mode
+ (dolist (ov (overlays-in (point-min) (point-max)))
+ (if (eq (overlay-get ov 'category)
+ 'preview-overlay)
+ (mn/text-scale--resize-fragment ov))))
+ ('org-mode
+ (dolist (ov (overlays-in (point-min) (point-max)))
+ (if (eq (overlay-get ov 'org-overlay-type)
+ 'org-latex-overlay)
+ (mn/text-scale--resize-fragment ov))))))
+
+(defun mn/text-scale--resize-fragment (ov)
+ (overlay-put
+ ov 'display
+ (cons 'image
+ (plist-put
+ (cdr (overlay-get ov 'display))
+ :scale (+ 1.0 (* 0.25 text-scale-mode-amount))))))
+
+(add-hook 'text-scale-mode-hook #'mn/text-scale-adjust-latex-previews)
+#+end_src
+
+*** Org Agenda
+#+begin_src emacs-lisp
+(after! org
+ (setq org-agenda-files
+ '("~/Documents/Org/" "~/Documents/Agenda/" "~/Notes/")))
+#+end_src
+
+*** Babel
+#+begin_src emacs-lisp
+;; (add-to-list 'org-src-lang-modes '("mathematica" . wolfram))
+(autoload 'wolfram-mode "wolfram-mode" nil t) (autoload 'run-wolfram "wolfram-mode" nil t) (setq wolfram-program "/Applications/Mathematica.app/Contents/MacOS/MathKernel")
+(add-to-list 'auto-mode-alist '("\.m$" . wolfram-mode)) (setq wolfram-path "/Users/michael/Library/Mathematica/Kernel")
+;; Load mathematica from contrib
+(org-babel-do-load-languages 'org-babel-load-languages
+ (append org-babel-load-languages
+ '((mathematica . t))
+ ))
+;; Sanitize output and deal with paths
+(setq org-babel-mathematica-command "~/.local/bin/mash.pl")
+;; Font-locking
+(add-to-list 'org-src-lang-modes '("mathematica" . wolfram))
+;; For wolfram-mode
+(setq mathematica-command-line "~/.local/bin/mash.pl")
+#+end_src
+
+*** Ansi Colour Codes
+Display ansi colour codes in org babel results.
+
+#+begin_src emacs-lisp
+(defun mn/babel-ansi ()
+ (when-let ((beg (org-babel-where-is-src-block-result nil nil)))
+ (save-excursion
+ (goto-char beg)
+ (when (looking-at org-babel-result-regexp)
+ (let ((end (org-babel-result-end))
+ (ansi-color-context-region nil))
+ (ansi-color-apply-on-region beg end))))))
+
+(add-hook 'org-babel-after-execute-hook 'mn/babel-ansi)
+#+end_src
+
+** Org Feed
+#+begin_src emacs-lisp
+(setq org-feed-alist
+ '(("Michael's Feed"
+ "https://michaelneuper.com/index.xml"
+ "~/Documents/Org/feeds.org" "Michael's Entries")))
+#+end_src
+
+** Org Roam
+*** Roam Config
+#+begin_src emacs-lisp
+(use-package! org-roam
+ :ensure t
+ :config
+ ;; Settings
+ (setq org-roam-directory (file-truename "~/Notes")
+ org-attach-id-dir "assets/")
+ (org-roam-db-autosync-enable)
+ ;; Keybindings
+ (map! :map org-mode-map
+ :leader
+ (:prefix ("r")
+ :desc "Insert node"
+ "i" #'org-roam-node-insert
+ :desc "Find node"
+ "f" #'org-roam-node-find
+ :desc "Capture to node"
+ "c" #'org-roam-capture
+ :desc "Toggle roam buffer"
+ "b" #'org-roam-buffer-toggle
+ :desc "Open random note"
+ "r" #'org-roam-node-random
+ :desc "Visit node"
+ "v" #'org-roam-node-visit))
+ (map! :leader ; unbind default doom binding
+ "n r n" nil))
+ ;; Capture templates
+ ;; (org-roam-capture-templates
+ ;; '(("d" "default" plain
+ ;; "%?"
+ ;; :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
+ ;; :unnarrowed t)
+ ;; ("m" "math" plain
+ ;; "%?"
+ ;; :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+startup: latexpreview\n")
+ ;; :unnarrowed t))))
+#+end_src
+
+*** Roam UI
+#+begin_src emacs-lisp
+(use-package! websocket
+ :after org-roam)
+
+(use-package! org-roam-ui
+ :after org-roam ;; or :after org
+ ;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
+ ;; a hookable mode anymore, you're advised to pick something yourself
+ ;; if you don't care about startup time, use
+ ;; :hook (after-init . org-roam-ui-mode)
+ :config
+ ;; Settings
+ (setq org-roam-ui-sync-theme t
+ org-roam-ui-follow t
+ org-roam-ui-update-on-save t
+ org-roam-ui-open-on-start t)
+ ;; Keybindings
+ (map! :leader
+ (:prefix "r"
+ :desc "Open UI"
+ "u" #'org-roam-ui-open)))
+#+end_src
+
+** Org Logseq
+#+begin_src emacs-lisp
+;; (setq org-logseq-dir "")
+#+end_src
+
+** Hugo
+*** Ox-Hugo
+#+begin_src emacs-lisp
+(use-package ox-hugo
+ :ensure t
+ :pin melpa
+ :after ox)
+#+end_src
+
+#+begin_src emacs-lisp
+(use-package blog
+ :commands (blog-publish-file
+ blog-generate-file-name
+ blog-read-list-items)
+ :preface
+ (defvar blog-capture-template
+ "#+hugo_base_dir: ../
+#+hugo_section: posts
+#+hugo_auto_set_lastmod: t
+#+options: tex:dvisvgm
+#+macro: kbd @@html:<kbd>$1</kbd>@@
+
+#+title: %(format \"%s\" blog--current-post-name)
+#+date: %(format-time-string \"%Y-%m-%d %h %H:%M\")
+#+hugo_tags: %(blog-read-list-items \"Select tags: \" 'blog-tags)
+#+hugo_categories: %(blog-read-list-items \"Select categories: \" 'blog-categories)
+#+hugo_custom_front_matter: :license %(format \"%S\" blog-license)
+
+%?"
+ "Org-capture template for blog posts.")
+ (defcustom blog-tags nil
+ "A list of tags used for posts."
+ :type '(repeat string)
+ :group 'blog)
+ (defcustom blog-categories nil
+ "A list of tags used for posts."
+ :type '(repeat string)
+ :group 'blog)
+ (defcustom blog-directory "~/blog"
+ "Location of the blog directory for org-capture."
+ :type 'string
+ :group 'blog)
+ (defcustom blog-license ""
+ "Blog license string."
+ :type 'string
+ :group 'blog)
+ (defvar blog--current-post-name nil
+ "Current post name for org-capture template.")
+ (defun blog-read-list-items (prompt var)
+ "Completing read items with the PROMPT from the VAR.
+
+VAR must be a quoted custom variable, which will be saved if new
+items were read by the `completing-read' function."
+ (let ((items (eval var)) item result)
+ (while (not (string-empty-p item))
+ (setq item (string-trim (or (completing-read prompt items) "")))
+ (unless (string-empty-p item)
+ (push item result)
+ (setq items (remove item items))
+ (unless (member item (eval var))
+ (customize-save-variable var (sort (cons item (eval var)) #'string<)))))
+ (string-join result " ")))
+ (defun blog-title-to-fname (title)
+ (thread-last
+ title
+ (replace-regexp-in-string "[[:space:]]" "-")
+ (replace-regexp-in-string "-+" "-")
+ (replace-regexp-in-string "[^[:alnum:]-]+" "")
+ downcase))
+ (defun blog-generate-file-name (&rest _)
+ (let ((title (read-string "Title: ")))
+ (setq blog--current-post-name title)
+ (find-file
+ (file-name-concat
+ (expand-file-name blog-directory)
+ "posts"
+ (format "%s-%s.org"
+ (format-time-string "%Y-%m-%d")
+ (blog-title-to-fname title))))))
+ (defun blog-publish-file ()
+ "Update '#+date:' tag, and rename the currently visited file.
+File name is updated to include the same date and current title."
+ (interactive)
+ (save-match-data
+ (let ((today (format-time-string "%Y-%m-%d"))
+ (now (format-time-string "%h %H:%M")))
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "^#\\+date:.*$")
+ (replace-match (format "#+date: %s %s" today now)))
+ (let* ((file-name (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "^#\\+title:[[:space:]]*\\(.*\\)$")
+ (blog-title-to-fname (match-string 1)))))
+ (condition-case nil
+ (rename-visited-file
+ (format "%s-%s.org" today
+ (if (string-match
+ "^[[:digit:]]\\{4\\}-[[:digit:]]\\{2\\}-[[:digit:]]\\{2\\}-\\(.*\\)$"
+ file-name)
+ (match-string 1 file-name)
+ file-name)))
+ (file-already-exists nil))
+ (save-buffer)))))
+ (provide 'blog))
+#+end_src
+
+* Other Packages
+** Spotify
+Enable and configure smudge.
+
+#+begin_src emacs-lisp
+(use-package! smudge
+ :init
+ (setq smudge-status-location 'modeline
+ smudge-transport 'connect) ; requires spotify premium
+ :config
+ ;; General keybindings
+ (map! :leader
+ (:prefix ("m" . "music")
+ :desc "Toggle shuffle"
+ "s" #'smudge-controller-toggle-shuffle
+ :desc "Toggle repeat"
+ "r" #'smudge-controller-toggle-repeat
+ :desc "Play/pause"
+ "SPC" #'smudge-controller-toggle-play
+ :desc "Next track"
+ "f" #'smudge-controller-next-track
+ :desc "Next track"
+ "n" #'smudge-controller-next-track
+ :desc "Previous track"
+ "b" #'smudge-controller-previous-track
+ :desc "My playlists"
+ "m" #'smudge-my-playlists
+ :desc "Select playback device"))
+ ;; Playlist keybindings
+ (map! :leader
+ (:prefix ("m p" . "playlists")
+ :desc "Featured playlists"
+ "f" #'smudge-featured-playlists
+ :desc "Search playlists"
+ "s" #'smudge-playlist-search
+ :desc "Show user's playlists"
+ "u" #'smudge-user-playlists
+ :desc "Create new playlist"
+ "c" #'smudge-create-playlist))
+ ;; Track keybindings
+ (map! :leader
+ (:prefix ("m t" . "tracks")
+ :desc "List recently played tracks"
+ "r" #'smudge-recently-played
+ :desc "Search for trakcs"
+ "s" #'smudge-track-search))
+ ;; Volume keybindings
+ (map! :leader
+ (:prefix ("m v" . "volume")
+ :desc "Increase volume"
+ "u" #'smudge-controller-volume-up
+ :desc "Decrease volume"
+ "d" #'smudge-controller-volume-down
+ :desc "Toggle mute"
+ "m" #'smudge-controller-voume-mute-unmute)))
+#+end_src
+
+** Calibre
+#+begin_src emacs-lisp
+(use-package calibredb
+ :defer t
+ :config
+ (setq calibredb-root-dir "~/Books"
+ calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir)
+ calibredb-library-alist '(("~/Books"))))
+#+end_src
+
+** Calc
+#+begin_src emacs-lisp
+(setq calc-angle-mode 'rad
+ calc-complex-format 'i
+ calc-prefer-frac t)
+#+end_src
diff --git a/init.el b/init.el
@@ -0,0 +1,247 @@
+;;; init.el -*- lexical-binding: t; -*-
+
+;; This file controls what Doom modules are enabled and what order they load
+;; in. Remember to run 'doom sync' after modifying it!
+
+;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
+;; documentation. There you'll find a link to Doom's Module Index where all
+;; of our modules are listed, including what flags they support.
+
+;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
+;; 'C-c c k' for non-vim users) to view its documentation. This works on
+;; flags as well (those symbols that start with a plus).
+;;
+;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
+;; directory (for easy access to its source code).
+
+(doom! :input
+ ;;bidi ; (tfel ot) thgir etirw uoy gnipleh
+ ;;chinese
+ ;;japanese
+ ;;layout ; auie,ctsrnm is the superior home row
+
+ :completion
+ (company
+ +childframe) ; the ultimate code completion backend
+ ;; corfu
+ ;; (helm
+ ;; +fuzzy
+ ;; +icons) ; the *other* search engine for love and life
+ ;;ido ; the other *other* search engine...
+ ;;ivy ; a search engine for love and life
+ (vertico
+ +icons) ; the search engine of the future
+
+ :ui
+ ;;deft ; notational velocity for Emacs
+ doom ; what makes DOOM look the way it does
+ doom-dashboard ; a nifty splash screen for Emacs
+ doom-quit ; DOOM quit-message prompts when you quit Emacs
+ (emoji
+ +unicode
+ +ascii
+ +github) ; 🙂
+ hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
+ ;;hydra
+ ;; indent-guides ; highlighted indent columns
+ (ligatures
+ ;; +extra
+ +fira) ; ligatures and symbols to make your code pretty again
+ minimap ; show a map of the code on the side
+ modeline ; snazzy, Atom-inspired modeline, plus API
+ ;; nav-flash ; blink cursor line after big motions
+ neotree ; a project drawer, like NERDTree for vim
+ ophints ; highlight the region an operation acts on
+ (popup
+ +defaults) ; tame sudden yet inevitable temporary windows
+ ;; tabs ; a tab bar for Emacs
+ (treemacs
+ +lsp) ; a project drawer, like neotree but cooler
+ unicode ; extended unicode support for various languages
+ (vc-gutter
+ +pretty) ; vcs diff in the fringe
+ vi-tilde-fringe ; fringe tildes to mark beyond EOB
+ (window-select
+ +winum) ; visually switch windows
+ workspaces ; tab emulation, persistence & separate workspaces
+ zen ; distraction-free coding or writing
+
+ :editor
+ (evil
+ +everywhere); come to the dark side, we have cookies
+ ;; file-templates ; auto-snippets for empty files
+ fold ; (nigh) universal code folding
+ (format
+ +lsp
+ +onsave) ; automated prettiness
+ ;;god ; run Emacs commands without modifier keys
+ ;;lispy ; vim for lisp, for people who don't like vim
+ multiple-cursors ; editing in many places at once
+ ;;objed ; text object editing for the innocent
+ ;;parinfer ; turn lisp into python, sort of
+ ;;rotate-text ; cycle region at point between text candidates
+ snippets ; my elves. They type so I don't have to
+ word-wrap ; soft wrapping with language-aware indent
+
+ :emacs
+ (dired
+ +dirvish
+ +icons) ; making dired pretty [functional]
+ electric ; smarter, keyword-based electric-indent
+ (ibuffer
+ +icons) ; interactive buffer management
+ undo ; persistent, smarter undo for your inevitable mistakes
+ vc ; version-control and Emacs, sitting in a tree
+
+ :term
+ eshell ; the elisp shell that works everywhere
+ ;;shell ; simple shell REPL for Emacs
+ ;;term ; basic terminal emulator for Emacs
+ vterm ; the best terminal emulation in Emacs
+
+ :checkers
+ (syntax
+ ;; +icons
+ +childframe) ; tasing you for every semicolon you forget
+ ;; spell ; tasing you for misspelling mispelling
+ ;; grammar ; tasing grammar mistake every you make
+
+ :tools
+ ;;ansible
+ biblio ; Writes a PhD for you (citation needed)
+ (debugger
+ +lsp) ; FIXME stepping through code, to help you add bugs
+ ;;direnv
+ ;;docker
+ editorconfig ; let someone else argue about tabs vs spaces
+ ;;ein ; tame Jupyter notebooks with emacs
+ (eval
+ +overlay) ; run code, run (also, repls)
+ ;;gist ; interacting with github gists
+ (lookup
+ +dictionary
+ +docsets
+ +offline) ; navigate your code and its documentation
+ (lsp
+ +peek) ; M-x vscode
+ (magit
+ +forge) ; a git porcelain for Emacs
+ ;;make ; run make tasks from Emacs
+ ;;pass ; password manager for nerds
+ pdf ; pdf enhancements
+ ;;prodigy ; FIXME managing external services & code builders
+ ;;rgb ; creating color strings
+ ;;taskrunner ; taskrunner for all your projects
+ ;;terraform ; infrastructure as code
+ ;;tmux ; an API for interacting with tmux
+ tree-sitter ; syntax and parsing, sitting in a tree...
+ ;;upload ; map local to remote projects via ssh/ftp
+
+ :os
+ (:if IS-MAC macos) ; improve compatibility with macOS
+ ;;tty ; improve the terminal Emacs experience
+
+ :lang
+ ;;agda ; types of types of types of types...
+ ;;beancount ; mind the GAAP
+ (cc
+ +lsp
+ +tree-sitter) ; C > C++ == 1
+ ;;clojure ; java with a lisp
+ ;;common-lisp ; if you've seen one lisp, you've seen them all
+ ;;coq ; proofs-as-programs
+ ;;crystal ; ruby at the speed of c
+ ;;csharp ; unity, .NET, and mono shenanigans
+ ;;data ; config/data formats
+ ;;(dart +flutter) ; paint ui and not much else
+ ;;dhall
+ ;;elixir ; erlang done right
+ ;;elm ; care for a cup of TEA?
+ emacs-lisp ; drown in parentheses
+ ;;erlang ; an elegant language for a more civilized age
+ ;;ess ; emacs speaks statistics
+ ;;factor
+ ;;faust ; dsp, but you get to keep your soul
+ ;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
+ ;;fsharp ; ML stands for Microsoft's Language
+ ;;fstar ; (dependent) types and (monadic) effects and Z3
+ ;;gdscript ; the language you waited for
+ ;;(go +lsp) ; the hipster dialect
+ ;;(graphql +lsp) ; Give queries a REST
+ ;;(haskell +lsp) ; a language that's lazier than I am
+ ;;hy ; readability of scheme w/ speed of python
+ ;;idris ; a language you can depend on
+ ;;json ; At least it ain't XML
+ (java
+ +tree-sitter
+ +lsp) ; the poster child for carpal tunnel syndrome
+ ;;javascript ; all(hope(abandon(ye(who(enter(here))))))
+ ;;julia ; a better, faster MATLAB
+ ;;kotlin ; a better, slicker Java(Script)
+ (latex
+ +cdlatex
+ +latexmk
+ +lsp
+ +fold) ; writing papers in Emacs has never been so fun
+ ;;lean ; for folks with too much to prove
+ ;;ledger ; be audit you can be
+ ;;lua ; one-based indices? one-based indices
+ markdown ; writing docs for people to ignore
+ ;;nim ; python + lisp at the speed of c
+ ;;nix ; I hereby declare "nix geht mehr!"
+ ;;ocaml ; an objective camel
+ (org
+ +dragndrop
+ ;; +gnuplot
+ +pandoc
+ +hugo
+ ;; +pomodoro
+ +present
+ ;; +pretty
+ +roam2) ; organize your plain life in plain text
+ ;;php ; perl's insecure younger brother
+ ;;plantuml ; diagrams for confusing people more
+ ;;purescript ; javascript, but functional
+ (python
+ +tree-sitter
+ +lsp) ; beautiful is better than ugly
+ ;;qt ; the 'cutest' gui framework ever
+ ;;racket ; a DSL for DSLs
+ ;;raku ; the artist formerly known as perl6
+ ;;rest ; Emacs as a REST client
+ ;;rst ; ReST in peace
+ ;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
+ rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
+ ;;scala ; java, but good
+ ;;(scheme +guile) ; a fully conniving family of lisps
+ (sh
+ +tree-sitter) ; she sells {ba,z,fi}sh shells on the C xor
+ ;;sml
+ ;;solidity ; do you need a blockchain? No.
+ ;;swift ; who asked for emoji variables?
+ ;;terra ; Earth and Moon in alignment for performance.
+ ;;web ; the tubes
+ ;;yaml ; JSON, but readable
+ ;;zig ; C, but simpler
+
+ :email
+ ;; (mu4e
+ ;; +org
+ ;; +gmail)
+ ;;notmuch
+ ;;(wanderlust +gmail)
+
+ :app
+ calendar
+ emms
+ everywhere ; *leave* Emacs!? You must be joking
+ ;;irc ; how neckbeards socialize
+ (rss
+ +org) ; emacs as an RSS reader
+ ;;twitter ; twitter client https://twitter.com/vnought
+
+ :config
+ literate
+ (default
+ +bindings
+ +smartparens))
diff --git a/packages.el b/packages.el
@@ -0,0 +1,108 @@
+;; -*- no-byte-compile: t; -*-
+;;; $DOOMDIR/packages.el
+
+;; To install a package with Doom you must declare them here and run 'doom sync'
+;; on the command line, then restart Emacs for the changes to take effect -- or
+;; use 'M-x doom/reload'.
+
+
+;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
+ ;(package! some-package)
+
+;; To install a package directly from a remote git repo, you must specify a
+;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
+;; https://github.com/radian-software/straight.el#the-recipe-format
+ ;(package! another-package
+ ; :recipe (:host github :repo "username/repo"))
+
+;; If the package you are trying to install does not contain a PACKAGENAME.el
+;; file, or is located in a subdirectory of the repo, you'll need to specify
+;; `:files' in the `:recipe':
+ ;(package! this-package
+ ; :recipe (:host github :repo "username/repo"
+ ; :files ("some-file.el" "src/lisp/*.el")))
+
+;; If you'd like to disable a package included with Doom, you can do so here
+;; with the `:disable' property:
+ ;(package! builtin-package :disable t)
+
+;; You can override the recipe of a built in package without having to specify
+;; all the properties for `:recipe'. These will inherit the rest of its recipe
+;; from Doom or MELPA/ELPA/Emacsmirror:
+ ;(package! builtin-package :recipe (:nonrecursive t))
+ ;(package! builtin-package-2 :recipe (:repo "myfork/package"))
+
+;; Specify a `:branch' to install a package from a particular branch or tag.
+;; This is required for some packages whose default branch isn't 'master' (which
+;; our package manager can't deal with; see radian-software/straight.el#279)
+ ;(package! builtin-package :recipe (:branch "develop"))
+
+;; Use `:pin' to specify a particular commit to install.
+ ;(package! builtin-package :pin "1a2b3c4d5e")
+
+
+;; Doom's packages are pinned to a specific commit and updated from release to
+;; release. The `unpin!' macro allows you to unpin single packages...
+ ;(unpin! pinned-package)
+;; ...or multiple packages
+ ;(unpin! pinned-package another-pinned-package)
+;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
+ ;(unpin! t)
+
+;; THEMES
+(package! one-themes)
+(package! atom-one-dark-theme)
+(package! spacemacs-theme)
+
+;; GAMES
+(package! chess)
+(package! pacmacs)
+(package! monkeytype)
+
+;; UI
+;; (package! dashboard)
+(package! nyan-mode)
+(package! good-scroll)
+(package! svg-lib)
+(package! svg-tag-mode)
+(package! info-colors)
+(package! page-break-lines)
+(package! all-the-icons)
+
+;; CODE
+(package! company-lsp)
+(package! company-tabnine)
+(package! lsp-pyright)
+(package! typst-ts-mode
+ :recipe (:host sourcehut :repo "meow_king/typst-ts-mode"))
+
+;; UTILITY
+(package! suggest)
+(package! calibredb)
+(package! nov)
+(package! helm-system-packages)
+(package! deadgrep)
+(package! xenops)
+(package! smudge)
+(package! mathpix
+ :recipe (:host github :repo "jethrokuan/mathpix.el"))
+(package! magit-todos)
+(package! org-ql)
+;; Org mode
+(package! org-download)
+(package! org-sticky-header)
+(when IS-MAC
+ (package! org-mac-link))
+ ; org-roam
+(package! org-roam-ui)
+(package! emacsql-sqlite3)
+ ; hugo
+(package! ox-hugo)
+
+(package! wolfram-mode)
+(package! ob-mathematica)
+
+(package! org :pin "806abc5a2bbcb5f884467a0145547221ba09eb59")
+
+(package! copilot
+ :recipe (:host github :repo "copilot-emacs/copilot.el" :files ("*.el")))