doom

My literate doom emacs config
git clone https://github.com/michaelneuper/doom.git
Files | Log | Refs

commit 13821509148189b286103f9d58b37c789a44c3c4
Author: Michael Neuper <michael@michaelneuper.com>
Date:   Thu, 14 Nov 2024 22:48:40 +0200

init

Diffstat:
Aconfig.el | 887+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aconfig.org | 1191+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainit.el | 247+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apackages.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")))