880 lines
31 KiB
EmacsLisp
880 lines
31 KiB
EmacsLisp
;;; 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)
|
|
|
|
(setq auth-sources '("~/.authinfo"))
|
|
|
|
(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)
|
|
|
|
(editorconfig-mode t)
|
|
|
|
;;(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)
|
|
|
|
;; (use-package naysayer-light-theme
|
|
;; :ensure nil
|
|
;; ;; :defer t
|
|
;; ;; :elpaca nil
|
|
;; :config
|
|
;; (load-theme 'naysayer-light t)
|
|
;; :load-path rs/lib-dir)
|
|
|
|
;; (use-package zenburn-theme
|
|
;; :config
|
|
;; (load-theme 'zenburn t))
|
|
|
|
;; (use-package tango-plus-theme
|
|
;; :config
|
|
;; (load-theme 'tango-plus t))
|
|
|
|
;; (custom-set-faces
|
|
;; ;; custom-set-faces was added by Custom.
|
|
;; ;; If you edit it by hand, you could mess it up, so be careful.
|
|
;; ;; Your init file should contain only one such instance.
|
|
;; ;; If there is more than one, they won't work right.
|
|
;; '(default ((t (:foreground "#d3b58d" :background "#041818"))))
|
|
;; '(custom-group-tag-face ((t (:underline t :foreground "lightblue"))) t)
|
|
;; '(custom-variable-tag-face ((t (:underline t :foreground "lightblue"))) t)
|
|
;; '(font-lock-builtin-face ((t nil)))
|
|
;; ; '(font-lock-comment-face ((t (:foreground "yellow"))))
|
|
;; '(font-lock-comment-face ((t (:foreground "#3fdflf"))))
|
|
;; '(font-lock-function-name-face ((((class color) (background dark)) (:foreground "white"))))
|
|
;; '(font-lock-keyword-face ((t (:foreground "white" ))))
|
|
;; ; '(font-lock-string-face ((t (:foreground "gray160" :background "gray16"))))
|
|
;; '(font-lock-string-face ((t (:foreground "#0fdfaf"))))
|
|
;; '(font-lock-variable-name-face ((((class color) (background dark)) (:foreground "#c8d4ec"))))
|
|
;; ; '(font-lock-warning-face ((t (:foreground "#695a46"))))
|
|
;; '(font-lock-warning-face ((t (:foreground "#504038"))))
|
|
;; '(highlight ((t (:foreground "navyblue" :background "darkseagreen2"))))
|
|
;; '(mode-line ((t (:inverse-video t))))
|
|
;; '(region ((t (:background "blue"))))
|
|
;; '(widget-field-face ((t (:foreground "white"))) t)
|
|
;; '(widget-single-line-field-face ((t (:background "darkgray"))) t))
|
|
|
|
;; (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")
|
|
(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))
|
|
|
|
(use-package forge
|
|
:after magit)
|
|
|
|
;; =========================
|
|
;; Programming Languages
|
|
;; =========================
|
|
|
|
(use-package nix-mode
|
|
:mode "\\.nix\\'")
|
|
|
|
(use-package python-mode
|
|
:mode ("\\.py\\'" . python-mode))
|
|
|
|
(use-package go-mode
|
|
:mode ("\\.go\\'" . go-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 <left>" . windmove-left)
|
|
("C-c <right>" . windmove-right)
|
|
("C-c <up>" . windmove-up)
|
|
("C-c <down>" . 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 "<mouse-4>") 'scroll-down-line)
|
|
(global-set-key (kbd "<mouse-5>") '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 "<C-down-mouse-4>") 'rs/zoom-frame)
|
|
(global-set-key (kbd "<C-down-mouse-5>") 'rs/zoom-frame-out)
|
|
(global-set-key (kbd "<C-wheel-up>") 'rs/zoom-frame)
|
|
(global-set-key (kbd "<C-wheel-down>") 'rs/zoom-frame-out)
|
|
|
|
;; =========================
|
|
;; Org
|
|
;; =========================
|
|
|
|
;; Agenda variables
|
|
(setq org-directory "~/NPersonal/") ; Non-absolute paths for agenda and
|
|
; capture templates will look here.
|
|
|
|
(setq org-agenda-files '("agenda.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 '(("agenda.org" :maxlevel . 2)
|
|
("archive.org" :level . 1)))
|
|
|
|
;; Archive location
|
|
(setq org-archive-location "archive.org::* Archived")
|
|
|
|
;;; Phase 3 variables
|
|
|
|
;; Denote (zettelkasten with markdown)
|
|
(use-package denote
|
|
:ensure t
|
|
:custom
|
|
(denote-directory "~/NPersonal/")
|
|
(denote-file-type 'markdown-yaml) ;; Use markdown with YAML front matter
|
|
(denote-known-keywords '("project" "idea" "ref" "meeting" "paper"))
|
|
(denote-prompts '(title keywords))
|
|
:bind
|
|
(("C-c n n" . denote) ;; Create new note
|
|
("C-c n f" . denote-open-or-create)
|
|
("C-c n i" . denote-link) ;; Insert link to note
|
|
("C-c n l" . denote-backlinks) ;; Show backlinks
|
|
("C-c n r" . denote-rename-file)
|
|
("C-c n k" . denote-keywords-add)
|
|
("C-c n K" . denote-keywords-remove))
|
|
:config
|
|
;; Enable denote links in org
|
|
(denote-rename-buffer-mode 1))
|
|
|
|
;; Denote org extras (better org integration)
|
|
(use-package denote-org-extras
|
|
:ensure nil
|
|
:after denote
|
|
:config
|
|
;; Create org links to denote files
|
|
(denote-org-extras-dblock-backlinks-mode 1)
|
|
:bind
|
|
(("C-c n b" . denote-org-extras-backlinks-for-heading)
|
|
("C-c n h" . denote-org-extras-link-to-heading)))
|
|
|
|
;;; 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!
|
|
:init
|
|
;; Load mu4e-org for email links (before org loads)
|
|
(with-eval-after-load 'org
|
|
(require 'mu4e-org nil t))
|
|
|
|
;; Open agenda on startup (deferred)
|
|
(add-hook 'elpaca-after-init-hook
|
|
(lambda ()
|
|
(run-with-idle-timer 1 nil #'org-agenda nil "n")))
|
|
|
|
:bind (:map global-map
|
|
("C-c a" . org-agenda) ; Agenda
|
|
("C-c c" . org-capture) ; Capture
|
|
("C-c l s" . org-store-link) ; Mnemonic: link → store
|
|
("C-c l i" . org-insert-link-global)) ; Mnemonic: link → insert
|
|
:custom
|
|
(org-time-stamp-rounding-minutes '(0 5)) ;; Round to 5 min
|
|
(org-read-date-prefer-future t)
|
|
(org-return-follows-link t) ;; RET follows links
|
|
;; Agenda settings
|
|
(org-agenda-window-setup 'current-window)
|
|
(org-agenda-start-with-log-mode t)
|
|
(org-agenda-include-diary nil)
|
|
(org-agenda-tags-column -80)
|
|
(org-agenda-block-separator ?─)
|
|
(org-agenda-time-grid '((daily today require-timed)
|
|
(800 1000 1200 1400 1600 1800 2000)
|
|
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄"))
|
|
(org-agenda-current-time-string "◀── now ──────────────────────────────────────")
|
|
: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" "Quick Capture" entry (file+headline "agenda.org" "Inbox")
|
|
"** 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+headline "agenda.org" "Inbox")
|
|
"** TODO %?\n%U\n%i\n%a")
|
|
("t" "Task" entry (file+headline "agenda.org" "Tasks")
|
|
"** TODO %?\n%U\n%i")
|
|
("m" "Meeting" entry (file+headline "agenda.org" "Meetings")
|
|
"** TODO %?\n%U\n%i\n%a")
|
|
;; Email capture
|
|
("e" "Email")
|
|
("ei" "Email to Inbox" entry (file+headline "agenda.org" "Inbox")
|
|
"** TODO %:subject\nFrom: %:fromname <%:fromaddress>\nEmail: %a\n%?")
|
|
("et" "Email to Tasks" entry (file+headline "agenda.org" "Tasks")
|
|
"** TODO %:subject\nFrom: %:fromname <%:fromaddress>\nEmail: %a\n%?")
|
|
("ef" "Email Follow-up" entry (file+headline "agenda.org" "Tasks")
|
|
"** TODO Follow up: %:subject\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\nFrom: %:fromname\nEmail: %a\n%?")))
|
|
(setq org-agenda-custom-commands
|
|
'(("n" "Dashboard"
|
|
((tags-todo "+DEADLINE<\"<today>\""
|
|
((org-agenda-overriding-header "Overdue!")))
|
|
(agenda "" ((org-agenda-span 'day)
|
|
(org-deadline-warning-days 7)
|
|
(org-agenda-time-grid nil)
|
|
(org-agenda-overriding-header "Today")))
|
|
(todo "STARTED"
|
|
((org-agenda-overriding-header "In Progress")))
|
|
(todo "WAITING"
|
|
((org-agenda-overriding-header "Waiting")))
|
|
(tags-todo "+DEADLINE>=\"<today>\"+DEADLINE<=\"<+7d>\""
|
|
((org-agenda-overriding-header "Due This Week")))
|
|
(tags-todo "inbox"
|
|
((org-agenda-overriding-header "Inbox")))
|
|
(agenda "" ((org-agenda-span 7)
|
|
(org-agenda-start-day "+1d")
|
|
(org-agenda-start-on-weekday nil)
|
|
(org-agenda-show-all-dates t)
|
|
(org-agenda-time-grid nil)
|
|
(org-agenda-overriding-header "Next 7 Days")))
|
|
(alltodo ""
|
|
((org-agenda-skip-function
|
|
'(org-agenda-skip-entry-if 'scheduled 'deadline 'todo '("STARTED" "WAITING")))
|
|
(org-agenda-overriding-header "Backlog")))))
|
|
("w" "Week View"
|
|
((agenda "" ((org-agenda-span 'week)
|
|
(org-deadline-warning-days 14)))))
|
|
("i" "Inbox" tags-todo "inbox")
|
|
("p" "Projects" tags-todo "project"))))
|
|
|
|
;; =========================
|
|
;; Email (mu4e)
|
|
;; =========================
|
|
|
|
(use-package mu4e
|
|
:ensure (:host github :repo "djcb/mu"
|
|
:files ("mu4e/*.el")
|
|
:pre-build (with-temp-file "mu4e/mu4e-config.el"
|
|
(insert (format "(defconst mu4e-mu-version %S)\n"
|
|
(string-trim (shell-command-to-string "mu --version | head -1 | awk '{print $2}'")))
|
|
"(provide 'mu4e-config)\n")))
|
|
:defer t
|
|
:commands (mu4e mu4e-compose-new)
|
|
:bind ("C-c e" . mu4e)
|
|
:config
|
|
;; Set mu binary path (for Nix)
|
|
(setq mu4e-mu-binary (or (executable-find "mu")
|
|
"/etc/profiles/per-user/rayandrew/bin/mu"))
|
|
|
|
;; Enable org-mode link support
|
|
(require 'mu4e-org)
|
|
|
|
;; General settings
|
|
(setq mu4e-maildir "~/mail")
|
|
(setq mu4e-get-mail-command "~/dotfiles/bin/path-shim mbsync -a")
|
|
(setq mu4e-update-interval 180) ;; Update every 3 minutes
|
|
(setq mu4e-change-filenames-when-moving t) ;; Required for mbsync
|
|
|
|
;; Sending mail via msmtp
|
|
(setq sendmail-program "msmtp")
|
|
(setq send-mail-function 'sendmail-send-it)
|
|
(setq message-sendmail-f-is-evil t)
|
|
(setq message-sendmail-extra-arguments '("--read-envelope-from"))
|
|
(setq message-send-mail-function 'message-send-mail-with-sendmail)
|
|
|
|
;; Don't keep message buffers around
|
|
(setq message-kill-buffer-on-exit t)
|
|
|
|
;; Display settings
|
|
(setq mu4e-headers-date-format "%Y-%m-%d")
|
|
(setq mu4e-headers-time-format "%H:%M")
|
|
(setq mu4e-view-show-addresses t)
|
|
(setq mu4e-view-show-images t)
|
|
(setq mu4e-compose-dont-reply-to-self t)
|
|
|
|
;; Prefer plain text over HTML
|
|
(setq mm-discouraged-alternatives '("text/html" "text/richtext"))
|
|
|
|
;; GPG signing (not by default)
|
|
(setq mml-secure-openpgp-sign-with-sender t)
|
|
(setq mm-sign-option nil) ;; don't sign by default
|
|
|
|
;; Keybinding to sign message (in compose buffer)
|
|
(defun mu4e-compose-sign-message ()
|
|
"Sign the current message with GPG."
|
|
(interactive)
|
|
(mml-secure-message-sign-pgpmime))
|
|
|
|
(add-hook 'mu4e-compose-mode-hook
|
|
(lambda ()
|
|
(local-set-key (kbd "C-c C-s") 'mu4e-compose-sign-message)))
|
|
|
|
;; Keybindings: r for reply, R for reply-all
|
|
(define-key mu4e-headers-mode-map (kbd "r") 'mu4e-compose-reply)
|
|
(define-key mu4e-headers-mode-map (kbd "R") 'mu4e-compose-wide-reply)
|
|
(define-key mu4e-view-mode-map (kbd "r") 'mu4e-compose-reply)
|
|
(define-key mu4e-view-mode-map (kbd "R") 'mu4e-compose-wide-reply)
|
|
|
|
;; Keybinding: e for refile (archive)
|
|
(define-key mu4e-headers-mode-map (kbd "e") 'mu4e-headers-mark-for-refile)
|
|
(define-key mu4e-view-mode-map (kbd "e") 'mu4e-view-mark-for-refile)
|
|
|
|
;; t to mark (u to unmark is default)
|
|
(define-key mu4e-headers-mode-map (kbd "t") 'mu4e-headers-mark-for-something)
|
|
|
|
;; Use completing-read (works with vertico)
|
|
(setq mu4e-completing-read-function 'completing-read)
|
|
|
|
;; Contexts for multiple accounts
|
|
(setq mu4e-contexts
|
|
`(,(make-mu4e-context
|
|
:name "uchicago"
|
|
:match-func (lambda (msg)
|
|
(when msg
|
|
(string-prefix-p "/uchicago" (mu4e-message-field msg :maildir))))
|
|
:vars '((user-mail-address . "rayandrew@uchicago.edu")
|
|
(user-full-name . "Ray Andrew")
|
|
(mu4e-drafts-folder . "/uchicago/Drafts")
|
|
(mu4e-sent-folder . "/uchicago/Sent")
|
|
(mu4e-trash-folder . "/uchicago/Trash")
|
|
(mu4e-refile-folder . "/uchicago/Archive")
|
|
(message-sendmail-extra-arguments . ("--read-envelope-from" "-a" "uchicago"))))
|
|
,(make-mu4e-context
|
|
:name "personal"
|
|
:match-func (lambda (msg)
|
|
(when msg
|
|
(string-prefix-p "/personal" (mu4e-message-field msg :maildir))))
|
|
:vars '((user-mail-address . "raydreww@gmail.com")
|
|
(user-full-name . "Ray Andrew")
|
|
(mu4e-drafts-folder . "/personal/[Gmail]/Drafts")
|
|
(mu4e-sent-folder . "/personal/[Gmail]/Sent Mail")
|
|
(mu4e-trash-folder . "/personal/[Gmail]/Trash")
|
|
(mu4e-refile-folder . "/personal/[Gmail]/All Mail")
|
|
(message-sendmail-extra-arguments . ("--read-envelope-from" "-a" "personal"))))))
|
|
|
|
;; Set default context
|
|
(setq mu4e-context-policy 'pick-first)
|
|
(setq mu4e-compose-context-policy 'ask-if-none)
|
|
|
|
;; Bookmarks
|
|
(setq mu4e-bookmarks
|
|
'((:name "Unread messages" :query "flag:unread AND NOT flag:trashed" :key ?u)
|
|
(:name "Today's messages" :query "date:today..now" :key ?t)
|
|
(:name "Last 7 days" :query "date:7d..now" :key ?w)
|
|
(:name "UChicago Inbox" :query "maildir:/uchicago/Inbox" :key ?i)
|
|
(:name "Personal Inbox" :query "maildir:/personal/Inbox" :key ?p))))
|
|
|
|
(use-package wakatime-mode
|
|
:config
|
|
(global-wakatime-mode))
|
|
|
|
;; (use-package editorconfig
|
|
;; :init
|
|
;; (setq editorconfig-lisp-use-default-indent t) ; restores alignment for elisp
|
|
;; :demand
|
|
;; :custom
|
|
;; (editorconfig-trim-whitespaces-mode 'ws-butler-mode)
|
|
;; :config
|
|
;; (editorconfig-mode 1))
|