;;; init.el --- Emacs configuration by chase. -*- lexical-binding: t -*- ;;; Commentary: ;;; Code: ;; Check Emacs version and warn if it is not supported (when (and (<= emacs-major-version 29) (< emacs-minor-version 4)) (warn (format "This config is designed for Emacs 29+, please upgrade."))) ;; display startup time (defun chase/display-startup-time () "Write init time and number of garbage collections to message buffer." (message "Emacs loaded in %s with %d garbage collections" (emacs-init-time) gcs-done)) (add-hook 'emacs-startup-hook #'chase/display-startup-time) ;; automatically create missing directories ;; source: https://emacsredux.com/blog/2022/06/12/auto-create-missing-directories/ (defun er-auto-create-missing-dirs () "Create missing parent directories automatically when opening a file." (let ((target-dir (file-name-directory buffer-file-name))) (unless (file-exists-p target-dir) (make-directory target-dir t)))) (add-to-list 'find-file-not-found-functions #'er-auto-create-missing-dirs) ;; no bars (add-hook 'window-setup-hook (lambda () (menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1))) ;; bootstrap straight (defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" (or (bound-and-true-p straight-base-dir) user-emacs-directory))) (bootstrap-version 7)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) (setq straight-use-package-by-default t) (setq use-package-always-demand t use-package-compute-statistics t) (use-package bind-key) (use-package diminish) ;; benchmark (use-package benchmark-init :config (add-hook 'after-init-hook #'benchmark-init/deactivate)) ;; set locale (set-language-environment "UTF-8") (prefer-coding-system 'utf-8-unix) (setq-default buffer-file-coding-system 'utf-8-unix) ;; a few basic config points (setq use-short-answers t) (setq native-comp-async-report-warnings-errors 'silent) ;; date & time stuff (use-package calendar :config (setq calendar-week-start-day 1)) ;; Monday (use-package time :after doom-modeline :init (setq display-time-default-load-average nil display-time-24hr-format t) (display-time-mode)) ;; battery (use-package fancy-battery :after doom-modeline) ;; anzu (use-package anzu :config (global-anzu-mode)) ;; become evil (use-package evil :init (setq evil-want-keybinding nil evil-want-integration t evil-respect-visual-line-mode t evil-undo-system 'undo-redo evil-want-fine-undo t) :config (evil-mode)) (use-package evil-anzu :after (evil anzu)) (use-package evil-collection :after evil :diminish evil-collection-unimpaired-mode :config (evil-collection-init)) (use-package vertico :custom (vertico-cycle t) :init (vertico-mode)) (use-package savehist :init (savehist-mode)) (use-package orderless :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completion-category-overrides '((file (styles partial-completion))))) ;; prevent laggy icons (setq inhibit-compacting-font-caches t) ;; make Emacs pretty (use-package nerd-icons :custom (nerd-icons-font-family "BlexMono Nerd Font")) (use-package nerd-icons-completion :config (nerd-icons-completion-mode)) (use-package nerd-icons-corfu :after corfu :config (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) (use-package nerd-icons-dired :hook (dired-mode . nerd-icons-dired-mode)) (use-package nerd-icons-ibuffer :hook (ibuffer-mode . nerd-icons-ibuffer-mode)) ;; theme stuff (use-package catppuccin-theme :config (load-theme 'catppuccin :no-confirm) (add-hook 'server-after-make-frame-hook #'catppuccin-reload)) ;; colourize colour names (use-package rainbow-mode :ensure nil ;; built-in package :hook (org-mode . rainbow-mode) (text-mode . rainbow-mode)) ;; make parentheses colourful (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) ;; misc aesthetic settings (global-hl-line-mode) (column-number-mode) ;; line numbers, not quite everywhere (add-hook 'prog-mode-hook #'display-line-numbers-mode) (add-hook 'text-mode #'display-line-numbers-mode) ;; move cursor to new help windows (setq help-window-select t) ;; less blinky cursor (setq blink-cursor-blinks 3) ;; move between windows easier (windmove-default-keybindings) ;; doom-modeline (use-package doom-modeline :hook (after-init . doom-modeline-mode)) ;; tab behaviour (setq-default indent-tabs-mode nil) (setq-default tab-width 4) ;; electric pair (electric-pair-mode t) ;; use ibuffer instead of Buffer Menu, it looks nicer (require 'ibuf-ext) (global-set-key (kbd "C-x C-b") 'ibuffer) (setq ibuffer-saved-filter-groups '(("Default" ("Terminal" (name . "^\\*terminal\\*$")) ("Nix" (mode . nix-ts-mode)) ("Code" (or (mode . c-ts-mode) (mode . c++-ts-mode) (mode . js-ts-mode) (mode . makefile-gmake-mode) (mode . python-ts-mode) (mode . rust-ts-mode))) ("Org" (mode . org-mode)) ("Dired" (mode . dired-mode)) ("Magit" (name . "^magit")) ("Emacs" (or (name . "^\\*Completions\\*$") (name . "^\\*Help\\*$") (name . "^\\*info\\*$") (name . "^\\*Messages\\*$") (name . "^\\*scratch\\*$")))))) (add-hook 'ibuffer-mode-hook (lambda () (ibuffer-switch-to-saved-filter-groups "Default"))) ;; git stuff (use-package magit) (use-package magit-todos :after magit) (use-package forge :after magit :init (setq forge-add-default-bindings nil)) (use-package git-modes) (use-package editorconfig :config (editorconfig-mode 1)) ;; treemacs stuff (use-package treemacs :bind (:map global-map ("M-0" . treemacs-select-window) ("C-x t t" . treemacs)) :config (setq treemacs-persist-file "~/.cache/emacs/treemacs-persist" treemacs-width 25)) (use-package treemacs-evil :after (treemacs evil)) (use-package treemacs-magit :after (treemacs magit)) (use-package treemacs-nerd-icons :after (treemacs nerd-icons) :config (treemacs-load-theme "nerd-icons")) ;; corfu (use-package corfu :custom (corfu-cycle t) (corfu-auto t) (corfu-auto-prefix 2) (corfu-auto-delay 0.2) (corfu-quit-at-boundary 'separator) (corfu-echo-documentation 0.25) :init (when (>= emacs-major-version 30) (global-completion-preview-mode 1)) (unless (display-graphic-p) (when (require 'corfu-terminal nil :noerror) (corfu-terminal-mode +1))) (global-corfu-mode 1) (corfu-history-mode 1)) ;; yasnippet config (use-package yasnippet :defer t :hook (prog-mode . yas-minor-mode) :config (setq yas-snippet-dirs '((expand-file-name "snippets/" user-emacs-directory) ;; personal (expand-file-name "work/" user-emacs-directory)))) ;; keep em separated ;; nix (use-package nix-ts-mode :defer t :mode "\\.nix\\'") ;; c (use-package c-ts-mode :straight nil :defer t :config (setq c-ts-mode-indent-style 'k&r) (setq c-ts-mode-indent-offset 4)) ;; python (use-package python :defer t :config (setq python-flymake-command '("ruff" "--quiet" "--stdin-filename=stdin" "-"))) ;; eglot (use-package eglot :straight nil :hook (c-ts-mode . eglot-ensure) (nix-ts-mode . eglot-ensure) (python-ts-mode . eglot-ensure) :config (setq eldoc-echo-area-display-truncation-message nil eldoc-echo-area-prefer-doc-buffer t max-mini-window-height 2) (dolist (mode '(((nix-mode nix-ts-mode) . ("nixd")))) (add-to-list 'eglot-server-programs mode))) ;; treesit-auto (use-package treesit-auto :custom (treesit-auto-install 'prompt) :config (treesit-auto-add-to-auto-mode-alist 'all) (setq treesit-font-lock-level 4) (global-treesit-auto-mode)) ;; CSV mode (use-package csv-mode :defer t) ;; markdown (use-package markdown-mode :defer t :mode ("README\\.md\\'" . gfm-mode) :config (setq markdown-gfm-uppercase-checkbox t markdown-enable-wiki-links t)) ;; powershell support (use-package powershell :defer t) ;; yaml (use-package yaml :defer t) ;; portage config for gentoo (use-package portage-modes :defer t) ;; pdf tools (use-package pdf-tools :defer t :pin manual ;; don't reinstall when package updates :mode ("\\.pdf\\'" . pdf-view-mode) :hook (pdf-view-mode-hook . (internal-show-cursor nil nil)) :config (setq-default pdf-view-display-size 'fit-page) (setq pdf-annot-activate-created-annotations t) (pdf-tools-install :no-query) (require 'pdf-occur)) ;; org stuff (use-package org :mode ("\\.\\(org\\|org_archive\\|txt\\)\\'" . org-mode) :hook (org-mode . visual-line-mode) (org-mode . (lambda () (add-hook 'after-save-hook #'org-babel-tangle :append :local))) :diminish visual-line-mode :config ;; looks (setq org-ellipsis "⤵" org-hide-emphasis-markers t org-startup-folded 'content org-src-fontify-natively t org-edit-src-content-indentation 0) ;; keybinds (define-key global-map "\C-cl" #'org-store-link) (define-key global-map "\C-ca" #'org-agenda) (global-set-key (kbd "C-c c") 'org-capture) ;; agenda (require 'find-lisp) (unless (file-exists-p "~/Documents/org") (make-directory "~/Documents/org" t)) (setq org-directory "~/Documents/org") (unless (file-exists-p (expand-file-name "gtd/" org-directory)) (make-directory (expand-file-name "gtd/" org-directory) t)) (setq chase/org-agenda-directory (expand-file-name "gtd/" org-directory)) (setq org-agenda-files (find-lisp-find-files chase/org-agenda-directory "\.org$")) (setq org-capture-templates '(("i" "Inbox" entry (file "gtd/inbox.org") "* TODO %?\n") ("n" "Note" entry (file "gtd/inbox.org") "* %? :NOTE:\n"))) ;; TODO (setq org-log-done 'time) (setq org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "HOLD(h)" "|" "DONE(d)" "|" "Cancelled(c)"))) (setq org-tag-alist '(("@errand" . ?e) ("@office" . ?o) ("@home" . ?h))) (setq org-refile-allow-creating-parent-nodes 'confirm org-refile-targets '(("projects.org" . (:level . 1)))) ;; source blocks (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) (add-to-list 'org-structure-template-alist '("py" . "src python")) (add-to-list 'org-structure-template-alist '("sh" . "src shell")) (add-to-list 'org-structure-template-alist '("ts" . "src typescript")) (add-to-list 'org-structure-template-alist '("json" . "src json")) (add-to-list 'org-structure-template-alist '("yaml" . "src yaml")) ;; babel (add-to-list 'org-babel-load-languages '(shell . t)) ;; fix yaml fontify (add-to-list 'org-src-lang-modes '("yaml" . yaml-ts)) ;; export (setq org-export-with-toc nil org-export-with-section-numbers nil) ;; LaTeX ;;(setq org-latex-compiler "xelatex") ;;(setq org-latex-listings 'minted ;;org-latex-pdf-process ;;'("latexmk -shell-escape -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f")) (use-package evil-org :after org :hook (org-mode . evil-org-mode) :diminish evil-org-mode :init (setq evil-want-C-i-jump nil) :config (require 'evil-org-agenda) (evil-org-set-key-theme '(navigation insert textobjects additional calendar)) (evil-org-agenda-set-keys)) (use-package org-roam :after org :bind (("C-c n l" . org-roam-buffer-toggle) ("C-c n f" . org-roam-node-find) ("C-c n g" . org-roam-graph) ("C-c n i" . org-roam-node-insert) ("C-c n c" . org-roam-capture) ;; Dailies ("C-c n j" . org-roam-dailies-capture-today)) :config (unless (file-exists-p (expand-file-name "roam/" org-directory)) (make-directory (expand-file-name "roam/" org-directory) t)) (setq org-roam-directory (expand-file-name "roam/" org-directory)) (require 'org-roam-protocol) (require 'org-roam-export) (org-roam-db-autosync-mode) (setq org-roam-capture-templates '(("m" "main" plain "%?" :if-new (file+head "main/${slug}.org" "#+title: ${title}\n") :unnarrowed t) ("r" "reference" plain "%?" :if-new (file+head "reference/${title}.org" "#+title: ${title}\n") :unnarrowed t))) (setq org-roam-capture-ref-templates '(("r" "ref" plain "%?" :target (file+head "reference/${slug}.org" "#+title: ${title}\n${body}\n") :unnarrowed t)))) (use-package org-superstar :after org :hook (org-mode . org-superstar-mode)) (use-package org-appear :after org :hook (org-mode . org-appear-mode) :config (setq org-appear-autolinks t)) ;; GitHub flavoured markdown export (use-package ox-gfm :after org) ;; hugo markdown export (use-package ox-hugo :after org) ;; HTML syntax highlighting (use-package htmlize :after org) (use-package ox-moderncv :straight nil :load-path "~/org-cv/" ;;(org-cv :type git :host gitlab :repo "Titan-C/org-cv")) :init (require 'ox-moderncv)) (use-package ox-hugocv :after org :straight (org-cv :type git :host gitlab :repo "Titan-C/org-cv"))) ;; spell checking (use-package ispell :custom (ispell-program-name "aspell") (ispell-silently-savep t)) (use-package flyspell :defer t :hook (markdown-mode . flyspell-mode) (org-mode . flyspell-mode) :diminish flyspell-mode) ;; flymake config (use-package flymake :straight nil :defer t :init (setq elisp-flymake-byte-compile-load-path load-path) :bind (:map global-map ("M-n" . flymake-goto-next-error) ("M-p" . flymake-goto-prev-error))) ;; windows printer (setq ps-printer-name t) (setq ps-lpr-command "C:/Program Files/gs/gs10.03.1/bin/gswin64c.exe") (setq ps-lpr-switches '("-q" "-dNOPAUSE" "-dBATCH" "-sDEVICE=mswinpr2" "-sPAPERSIZE=a7")) (use-package emms) (provide 'init) ;;; init.el ends here