;;; post-init.el --- Post Initalization -*- no-byte-compile: t; lexical-binding: t; -*- ;; Auto-revert in Emacs is a feature that automatically updates the ;; contents of a buffer to reflect changes made to the underlying file ;; on disk. (add-hook 'elpaca-after-init-hook #'global-auto-revert-mode) ;; recentf is an Emacs package that maintains a list of recently ;; accessed files, making it easier to reopen files you have worked on ;; recently. (add-hook 'elpaca-after-init-hook #'(lambda() (let ((inhibit-message t)) (recentf-mode 1)))) (add-hook 'kill-emacs-hook #'recentf-cleanup) ;; savehist is an Emacs feature that preserves the minibuffer history between ;; sessions. It saves the history of inputs in the minibuffer, such as commands, ;; search strings, and other prompts, to a file. This allows users to retain ;; their minibuffer history across Emacs restarts. (add-hook 'elpaca-after-init-hook #'savehist-mode) ;; save-place-mode enables Emacs to remember the last location within a file ;; upon reopening. This feature is particularly beneficial for resuming work at ;; the precise point where you previously left off. (add-hook 'elpaca-after-init-hook #'save-place-mode) (use-package emacs :elpaca nil :ensure nil :custom (delete-selection-mode t) ;; Select text and delete it by typing. (electric-indent-mode nil) ;; Turn off the weird indenting that Emacs does by default. (electric-pair-mode t) ;; Turns on automatic parens pairing (blink-cursor-mode nil) ;; Don't blink cursor (global-auto-revert-mode t) ;; Automatically reload file and show changes if the file has changed (indent-tabs-mode nil) ;;(dired-kill-when-opening-new-dired-buffer t) ;; Dired don't create new buffer (recentf-mode t) ;; Enable recent file mode (recentf-max-saved-items 50) ;;(global-visual-line-mode t) ;; Enable truncated lines ;;(display-line-numbers-type 'relative) ;; Relative line numbers (global-display-line-numbers-mode t) ;; Display line numbers (split-width-threshold nil) ;; Splitting behavior :bind (([escape] . keyboard-escape-quit) ("C-x c" . compile))) ;; ========================= ;; Theme ;; ========================= (use-package naysayer-theme :ensure nil ;; :defer t ;; :elpaca nil :config (load-theme 'naysayer t) :load-path rs/lib-dir) (global-font-lock-mode 1) (set-cursor-color "lightgreen") (set-background-color "#072626") ;; (global-set-key [C-return] 'save-buffer) ;(set-face-attribute 'default nil :font "Anonymous Pro-14") ;; (set-face-attribute 'default nil :font "Consolas-174") (set-face-foreground 'font-lock-builtin-face "lightgreen") ;; ========================= ;; Better UX ;; ========================= (use-package vertico ;; (Note: It is recommended to also enable the savehist package.) :ensure t :defer t :commands (vertico-mode vertico-multiform-mode) :custom (vertico-cycle t) (vertico-multiform-commands '((consult-imenu buffer indexed) (find-file flat (vertico-cycle . t)) (execute-extended-command flat (vertico-cycle . t)))) (vertico-multiform-categories '((consult-grep buffer))) :hook (elpaca-after-init . vertico-mode) (elpaca-after-init . vertico-multiform-mode)) (use-package orderless ;; Vertico leverages Orderless' flexible matching capabilities, allowing users ;; to input multiple patterns separated by spaces, which Orderless then ;; matches in any order against the candidates. :ensure t :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completion-category-overrides '((file (styles partial-completion))))) (use-package marginalia ;; Marginalia allows Embark to offer you preconfigured actions in more contexts. ;; In addition to that, Marginalia also enhances Vertico by adding rich ;; annotations to the completion candidates displayed in Vertico's interface. :ensure t :defer t :commands (marginalia-mode marginalia-cycle) :hook (elpaca-after-init . marginalia-mode)) (use-package embark ;; Embark is an Emacs package that acts like a context menu, allowing ;; users to perform context-sensitive actions on selected items ;; directly from the completion interface. :ensure t :defer t :commands (embark-act embark-dwim embark-export embark-collect embark-bindings embark-prefix-help-command) :bind (("C-." . embark-act) ;; pick some comfortable binding ("C-;" . embark-dwim) ;; good alternative: M-. ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings' :init (setq prefix-help-command #'embark-prefix-help-command) :config ;; Hide the mode line of the Embark live/completions buffers (add-to-list 'display-buffer-alist '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil (window-parameters (mode-line-format . none))))) (use-package embark-consult :ensure t :hook (embark-collect-mode . consult-preview-at-point-mode)) (use-package consult :ensure t :bind (;; C-c bindings in `mode-specific-map' ("C-c M-x" . consult-mode-command) ("C-c h" . consult-history) ("C-c k" . consult-kmacro) ("C-c m" . consult-man) ("C-c i" . consult-info) ([remap Info-search] . consult-info) ;; C-x bindings in `ctl-x-map' ("C-x M-:" . consult-complex-command) ("C-x b" . consult-buffer) ("C-x 4 b" . consult-buffer-other-window) ("C-x 5 b" . consult-buffer-other-frame) ("C-x t b" . consult-buffer-other-tab) ("C-x r b" . consult-bookmark) ("C-x p b" . consult-project-buffer) ;; Custom M-# bindings for fast register access ("M-#" . consult-register-load) ("M-'" . consult-register-store) ("C-M-#" . consult-register) ;; Other custom bindings ("M-y" . consult-yank-pop) ;; M-g bindings in `goto-map' ("M-g e" . consult-compile-error) ("M-g f" . consult-flymake) ("M-g g" . consult-goto-line) ("M-g M-g" . consult-goto-line) ("M-g o" . consult-outline) ("M-g m" . consult-mark) ("M-g k" . consult-global-mark) ("M-g i" . consult-imenu) ("M-g I" . consult-imenu-multi) ;; M-s bindings in `search-map' ("M-s d" . consult-find) ("M-s c" . consult-locate) ("M-s g" . consult-grep) ("M-s G" . consult-git-grep) ("M-s r" . consult-ripgrep) ("M-s l" . consult-line) ("M-s L" . consult-line-multi) ("M-s k" . consult-keep-lines) ("M-s u" . consult-focus-lines) ;; Isearch integration ("M-s e" . consult-isearch-history) :map isearch-mode-map ("M-e" . consult-isearch-history) ("M-s e" . consult-isearch-history) ("M-s l" . consult-line) ("M-s L" . consult-line-multi) ;; Minibuffer history :map minibuffer-local-map ("M-s" . consult-history) ("M-r" . consult-history)) ;; Enable automatic preview at point in the *Completions* buffer. :hook (completion-list-mode . consult-preview-at-point-mode) :init ;; Optionally configure the register formatting. This improves the register (setq register-preview-delay 0.5 register-preview-function #'consult-register-format) ;; Optionally tweak the register preview window. (advice-add #'register-preview :override #'consult-register-window) ;; Use Consult to select xref locations with preview (setq xref-show-xrefs-function #'consult-xref xref-show-definitions-function #'consult-xref) :config (consult-customize consult-theme :preview-key '(:debounce 0.2 any) consult-ripgrep consult-git-grep consult-grep consult-bookmark consult-recent-file consult-xref consult--source-bookmark consult--source-file-register consult--source-recent-file consult--source-project-recent-file ;; :preview-key "M-." :preview-key '(:debounce 0.4 any)) (setq consult-narrow-key "<")) ;; Outline Indent (use-package outline-indent :ensure t :defer t :commands outline-indent-minor-mode :init ;; The minor mode can also be automatically activated for a certain modes. ;; For example for Python and YAML: (add-hook 'python-mode-hook #'outline-indent-minor-mode) (add-hook 'python-ts-mode-hook #'outline-indent-minor-mode) (add-hook 'yaml-mode-hook #'outline-indent-minor-mode) (add-hook 'yaml-ts-mode-hook #'outline-indent-minor-mode) :custom (outline-indent-ellipsis " ▼ ")) ;; Dired (defun rs/dired-copy-path-at-point () (interactive) (dired-copy-filename-as-kill 0)) (use-package dired :ensure nil :bind (("C-x -" . dired-jump) ("C-x e" . dired-jump) (:map dired-mode-map ("-" . dired-up-directory) ("W" . rs/dired-copy-path-at-point))) :custom (dired-deletion-confirmer #'y-or-n-p) (dired-dwim-target t) ;; (dired-listing-switches "-Alh") (dired-listing-switches "-AlhcF --group-directories-first") (dired-auto-revert-buffer t)) (use-package dired-x :after dired :ensure nil) ;; Dired buffers: Automatically hide file details (permissions, size, ;; modification date, etc.) and all the files in the `dired-omit-files' regular ;; expression for a cleaner display. (add-hook 'dired-mode-hook #'dired-hide-details-mode) ;; Hide files from dired (setq dired-omit-files (concat "\\`[.]\\'" "\\|\\(?:\\.js\\)?\\.meta\\'" "\\|\\.\\(?:elc|a\\|o\\|pyc\\|pyo\\|swp\\|class\\)\\'" "\\|^\\.DS_Store\\'" "\\|^\\.\\(?:svn\\|git\\)\\'" "\\|^\\.ccls-cache\\'" "\\|^__pycache__\\'" "\\|^\\.project\\(?:ile\\)?\\'" "\\|^flycheck_.*" "\\|^flymake_.*")) (add-hook 'dired-mode-hook #'dired-omit-mode) ;; Undo Tree (use-package undo-tree :ensure t :defer t ;; :demand t :diminish :bind (("C-M-u" . undo-tree-visualize) ("M-_" . undo-tree-redo) ("M--" . go-back-to-last-edit) :map undo-tree-map (("C-x u" . nil))) :custom (undo-tree-visualizer-diff t) (undo-tree-enable-undo-in-region t) ;; (undo-tree-auto-save-history nil) (undo-tree-history-directory-alist `((".*" . ,(expand-file-name "undo" rs/emacs-dir)))) ;; (setq undo-tree-visualizer-relative-timestamps nil) ;; (setq undo-tree-visualizer-timestamps t) :config (defun go-back-to-last-edit () "Jump back to the last change in the current buffer." (interactive) (ignore-errors (let ((inhibit-message t)) (undo-tree-undo) (undo-tree-redo)))) (defun undo-tree-split-side-by-side (original-function &rest args) "Split undo-tree side-by-side" (let ((split-height-threshold nil) (split-width-threshold 0)) (apply original-function args))) (advice-add 'undo-tree-visualize :around #'undo-tree-split-side-by-side) :hook (elpaca-after-init . global-undo-tree-mode)) (use-package multiple-cursors :bind (("C-S-c C-S-c" . mc/edit-lines) ("C-M-SPC" . set-rectangular-region-anchor) ("C->" . mc/mark-next-like-this) ("C-<" . mc/mark-previous-like-this) ("C-c C-<" . mc/mark-all-like-this) ("C-\"" . mc/skip-to-next-like-this) ("C-:" . mc/skip-to-previous-like-this))) (use-package move-text :bind (("M-p" . move-text-up) ("M-n" . move-text-down))) ;; ========================= ;; Magit ;; ========================= (use-package magit :commands magit-status :bind ("C-x g" . magit)) ;; ========================= ;; Programming Languages ;; ========================= (use-package nix-mode :mode "\\.nix\\'") (use-package python-mode :mode ("\\.py\\'" . python-mode)) (use-package csv-mode :mode ("\\.csv\\'" . csv-mode)) (use-package markdown-mode :mode ("\\.md\\'" . markdown-mode)) (use-package lua-mode :mode ("\\.lua\\'" . lua-mode)) (use-package yaml-mode :mode (("\\.yml\\'" . yaml-mode) ("\\.yaml\\'" . yaml-mode))) (use-package yasnippet :commands (yas-minor-modeb yas-reload-all) :config (yas-reload-all) :hook ;; (elpaca-after-init . yas-reload-all) (prog-mode . yas-minor-mode)) (use-package yasnippet-snippets :after yasnippet) (use-package clipetty :hook (elpaca-after-init . global-clipetty-mode)) ;; ========================= ;; Miscellaneous ;; ========================= (global-unset-key (kbd "C-M-_")) ;; unbind redo-undo (use-package diminish) (use-package rainbow-mode :commands (rainbow-mode)) (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) (use-package term-keys :ensure (:host github :repo "CyberShadow/term-keys") :config (unless (display-graphic-p) (term-keys-mode t))) (use-package windmove :elpaca nil :bind (("C-c " . windmove-left) ("C-c " . windmove-right) ("C-c " . windmove-up) ("C-c " . windmove-down))) (use-package ace-window :defer t :commands (ace-window) :bind ("C-x C-o" . ace-window)) ;; (use-package compat) (use-package transient) (use-package compile-angel :diminish :ensure t :demand t :config ;; Set `compile-angel-verbose` to nil to suppress output from compile-angel. ;; Drawback: The minibuffer will not display compile-angel's actions. (setq compile-angel-verbose nil) (compile-angel-on-load-mode) (add-hook 'emacs-lisp-mode-hook #'compile-angel-on-save-local-mode)) (use-package which-key ;; :elpaca nil :defer t :commands which-key-mode :hook (elpaca-after-init . which-key-mode) :custom (which-key-idle-delay 1.5) (which-key-idle-secondary-delay 0.25) (which-key-add-column-padding 1) (which-key-max-description-length 40)) (unless (and (eq window-system 'mac) (bound-and-true-p mac-carbon-version-string)) ;; Enables `pixel-scroll-precision-mode' on all operating systems and Emacs ;; versions, except for emacs-mac. ;; ;; Enabling `pixel-scroll-precision-mode' is unnecessary with emacs-mac, as ;; this version of Emacs natively supports smooth scrolling. ;; https://bitbucket.org/mituharu/emacs-mac/commits/65c6c96f27afa446df6f9d8eff63f9cc012cc738 (setq pixel-scroll-precision-use-momentum nil) ; Precise/smoother scrolling (pixel-scroll-precision-mode 1)) (unless (display-graphic-p) (xterm-mouse-mode 1) (global-set-key (kbd "") 'scroll-down-line) (global-set-key (kbd "") 'scroll-up-line)) ;; Display the time in the modeline (display-time-mode 1) ;; Paren match highlighting (show-paren-mode 1) ;; Track changes in the window configuration, allowing undoing actions such as ;; closing windows. (winner-mode 1) ;; Replace selected text with typed text (delete-selection-mode 1) ;; Configure Emacs to ask for confirmation before exiting (setq confirm-kill-emacs 'y-or-n-p) (use-package uniquify :ensure nil :custom (uniquify-buffer-name-style 'reverse) (uniquify-separator "•") (uniquify-after-kill-buffer-p t) (uniquify-ignore-buffers-re "^\\*")) ;; Window dividers separate windows visually. Window dividers are bars that can ;; be dragged with the mouse, thus allowing you to easily resize adjacent ;; windows. ;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Dividers.html (add-hook 'elpaca-after-init-hook #'window-divider-mode) ;; Enable on-the-fly spell checking (Flyspell mode). (add-hook 'text-mode-hook #'flyspell-mode) ;; Change split behavior (defun delete-window-evenly () (interactive) (command-execute 'delete-window) (command-execute 'balance-windows)) (global-set-key (kbd "C-x 0") 'delete-window-evenly) (defun split-vertical-evenly () (interactive) (command-execute 'split-window-vertically) (command-execute 'balance-windows)) (global-set-key (kbd "C-x 2") 'split-vertical-evenly) (defun split-horizontal-evenly () (interactive) (command-execute 'split-window-horizontally) (command-execute 'balance-windows)) (global-set-key (kbd "C-x 3") 'split-horizontal-evenly) ;; Increase/Decrease Font (defun rs/zoom-frame (&optional amt frame) "Increaze FRAME font size by amount AMT. Defaults to selected frame if FRAME is nil, and to 1 if AMT is nil." (interactive "p") (let* ((frame (or frame (selected-frame))) (font (face-attribute 'default :font frame)) (size (font-get font :size)) (amt (or amt 1)) (new-size (+ size amt))) (set-frame-font (font-spec :size new-size) t `(,frame)) (message "Frame's font new size: %d" new-size))) (defun rs/zoom-frame-out (&optional amt frame) "Call `rs/zoom-frame' with negative argument." (interactive "p") (rs/zoom-frame (- (or amt 1)) frame)) (global-set-key (kbd "C-=") 'rs/zoom-frame) (global-set-key (kbd "C--") 'rs/zoom-frame-out) (global-set-key (kbd "") 'rs/zoom-frame) (global-set-key (kbd "") 'rs/zoom-frame-out) (global-set-key (kbd "") 'rs/zoom-frame) (global-set-key (kbd "") 'rs/zoom-frame-out) ;; ========================= ;; Org ;; ========================= ;; Agenda variables (setq org-directory "~/Documents/org/") ; Non-absolute paths for agenda and ; capture templates will look here. (setq org-agenda-files '("inbox.org" "work.org")) ;; Default tags (setq org-tag-alist '( ;; locale (:startgroup) ("home" . ?h) ("work" . ?w) ("school" . ?s) (:endgroup) (:newline) ;; scale (:startgroup) ("one-shot" . ?o) ("project" . ?j) ("tiny" . ?t) (:endgroup) ;; misc ("meta") ("review") ("reading"))) ;; Org-refile: where should org-refile look? (setq org-refile-targets 'FIXME) ;;; Phase 3 variables ;; Org-roam variables (setq org-roam-directory "~/Documents/org-roam/") (setq org-roam-index-file "~/Documents/org-roam/index.org") ;;; Optional variables ;; Advanced: Custom link types ;; This example is for linking a person's 7-character ID to their page on the ;; free genealogy website Family Search. (setq org-link-abbrev-alist '(("family_search" . "https://www.familysearch.org/tree/person/details/%s"))) (use-package org :elpaca nil :hook ((org-mode . visual-line-mode) ; wrap lines at word breaks (org-mode . flyspell-mode)) ; spell checking! :bind (:map global-map ("C-c l s" . org-store-link) ; Mnemonic: link → store ("C-c l i" . org-insert-link-global)) ; Mnemonic: link → insert :config (require 'oc-csl) ; citation support (add-to-list 'org-export-backends 'md) (setf (cdr (assoc 'file org-link-frame-setup)) 'find-file) (setq org-export-with-smart-quotes t) (setq org-todo-keywords '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!)" "OBSOLETE(o@)"))) (setq org-outline-path-complete-in-steps nil) (setq org-refile-use-outline-path 'file) (setq org-capture-templates '(("c" "Default Capture" entry (file "inbox.org") "* TODO %?\n%U\n%i") ;; Capture and keep an org-link to the thing we're currently working with ("r" "Capture with Reference" entry (file "inbox.org") "* TODO %?\n%U\n%i\n%a") ;; Define a section ("w" "Work") ("wm" "Work meeting" entry (file+headline "work.org" "Meetings") "** TODO %?\n%U\n%i\n%a") ("wr" "Work report" entry (file+headline "work.org" "Reports") "** TODO %?\n%U\n%i\n%a"))) (setq org-agenda-custom-commands '(("n" "Agenda and All Todos" ((agenda) (todo))) ("w" "Work" agenda "" ((org-agenda-files '("work.org")))))))