From 5c590db7901f6e0f0a089bcf71401d6a4c9ba1d3 Mon Sep 17 00:00:00 2001 From: tdback Date: Wed, 5 Feb 2025 22:22:29 -0500 Subject: initial: we are SO back --- lisp/td-common.el | 145 +++++++++++++++++++++++++++++++++++++++++ lisp/td-dired.el | 27 ++++++++ lisp/td-evil.el | 33 ++++++++++ lisp/td-functions.el | 64 ++++++++++++++++++ lisp/td-mu4e.el | 63 ++++++++++++++++++ lisp/td-org.el | 172 +++++++++++++++++++++++++++++++++++++++++++++++++ lisp/td-present.el | 27 ++++++++ lisp/td-programming.el | 123 +++++++++++++++++++++++++++++++++++ lisp/td-writing.el | 22 +++++++ 9 files changed, 676 insertions(+) create mode 100644 lisp/td-common.el create mode 100644 lisp/td-dired.el create mode 100644 lisp/td-evil.el create mode 100644 lisp/td-functions.el create mode 100644 lisp/td-mu4e.el create mode 100644 lisp/td-org.el create mode 100644 lisp/td-present.el create mode 100644 lisp/td-programming.el create mode 100644 lisp/td-writing.el (limited to 'lisp') diff --git a/lisp/td-common.el b/lisp/td-common.el new file mode 100644 index 0000000..7e71f1b --- /dev/null +++ b/lisp/td-common.el @@ -0,0 +1,145 @@ +;;; -*- lexical-binding: t; -*- + +(use-package async + :ensure t + :config + (async-bytecomp-package-mode 1)) + +(use-package beframe + :ensure t + :config + (global-set-key (kbd "C-c b") 'beframe-prefix-map) + (beframe-mode 1)) + +(use-package consult + :ensure t + :demand t + :bind (("C-s" . consult-ripgrep) + ("C-M-l" . consult-imenu) + ("C-M-j" . consult-buffer) + ("C-x C-b" . consult-buffer) + :map minibuffer-local-map + ("C-r" . consult-history))) + +(use-package consult-dir + :ensure t + :bind (("C-x C-d" . consult-dir) + :map vertico-map + ("C-x C-d" . consult-dir) + ("C-x C-j" . consult-dir-jump-file)) + :custom + (consult-dir-project-list-function nil)) + +(use-package doom-modeline + :ensure t + :init + (doom-modeline-mode 1) + :custom + (doom-modeline-height 10) + (doom-modeline-buffer-encoding nil) + (doom-modeline-modal-icon nil)) + +(use-package ef-themes + :ensure t + :config + ;; By default start with a light theme. + (load-theme 'ef-day t)) + +(use-package embark + :ensure t + :bind (("C-." . embark-act) + ("M-." . embark-dwim) + ("C-h B" . embark-bindings)) + :config + ;; Remove mixed indicator to prevent popup from being displayed automatically. + (delete #'embark-mixed-indicator embark-indicators) + (add-to-list 'embark-indicators 'embark-minimal-indicator) + + ;; Use embark to show command prefix help. + (setq prefix-help-command #'embark-prefix-help-command)) + +(use-package embark-consult + :ensure t + :after embark) + +(use-package helpful + :ensure t + :custom + (counsel-describe-function-function #'helpful-callable) + (counsel-describe-variable-function #'helpful-variable) + :bind + ([remap describe-function] . helpful-function) + ([remap describe-command] . helpful-command) + ([remap describe-symbol] . helpful-symbol) + ([remap describe-variable] . helpful-variable) + ([remap describe-key] . helpful-key)) + +(use-package marginalia + :ensure t + :after vertico + :custom + (marginalia-annotators '(marginalia-annotators-heavy + marginalia-annotators-light + nil)) + :config + (marginalia-mode)) + +(use-package no-littering + :ensure t + :demand t + :config + ;; Set custom-file to a file that won't be tracked by git. + (setq custom-file + (let ((custom-file "custom.el")) + (if (boundp 'server-socket-dir) + (expand-file-name custom-file server-socket-dir) + (no-littering-expand-etc-file-name custom-file)))) + (when (file-exists-p custom-file) + (load custom-file t)) + + ;; Don't litter project folders with backup files. + (let ((backup-dir (no-littering-expand-var-file-name "backup/"))) + (make-directory backup-dir t) + (setq backup-directory-alist + `(("\\`/tmp/" . nil) + ("\\`/dev/shm/" . nil) + ("." . ,backup-dir)))) + + ;; Tidy up auto-save files. + (setq auto-save-default nil) + (let ((auto-save-dir (no-littering-expand-var-file-name "auto-save/"))) + (make-directory auto-save-dir t) + (setq auto-save-file-name-transforms + `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'" ,(concat temporary-file-directory "\\2") t) + ("\\`\\(/tmp\\|/dev/shm\\)\\([^/]*/\\)*\\(.*\\)\\'" "\\3") + ("." ,auto-save-dir t))))) + +(use-package savehist + :ensure t + :init + (savehist-mode)) + +(use-package vertico + :ensure t + :demand t + :bind (:map vertico-map + ("C-j" . vertico-next) + ("C-k" . vertico-previous) + ("C-f" . vertico-exit-input) + :map minibuffer-local-map + ("M-h" . vertico-directory-up)) + :custom + (vertico-cycle t) + :config + (require 'vertico-directory) + (vertico-mode)) + +(use-package which-key + :ensure t + :defer 0 + :diminish which-key-mode + :config + (setq which-key-idle-delay 0.5) + (which-key-mode)) + +(provide 'td-common) diff --git a/lisp/td-dired.el b/lisp/td-dired.el new file mode 100644 index 0000000..d1a6b72 --- /dev/null +++ b/lisp/td-dired.el @@ -0,0 +1,27 @@ +;;; -*- lexical-binding: t; -*- + +(use-package dired + :ensure nil + :commands (dired dired-jump) + :hook ((dired-mode . dired-hide-details-mode)) + :bind (:map dired-mode-map ("C-x C-j" . dired-jump)) + :config + (setq dired-listing-switches "-Agho --group-directories-first" + dired-omit-files "^\\.[^.].*" + dired-omit-verbose nil + dired-hide-detailes-hide-symlink-targets nil + dired-kill-when-opening-new-dired-buffer t + delete-by-moving-to-trash t)) + +(use-package all-the-icons-dired + :ensure t + :hook (dired-mode . all-the-icons-dired-mode)) + +(use-package dired-hide-dotfiles + :ensure t + :hook (dired-mode . dired-hide-dotfiles-mode) + :config + (evil-collection-define-key 'normal 'dired-mode-map + "H" 'dired-hide-dotfiles-mode)) + +(provide 'td-dired) diff --git a/lisp/td-evil.el b/lisp/td-evil.el new file mode 100644 index 0000000..afa92a7 --- /dev/null +++ b/lisp/td-evil.el @@ -0,0 +1,33 @@ +;;; -*- lexical-binding: t; -*- + +(use-package evil + :init + (setq evil-want-integration t) + (setq evil-want-keybinding nil) + (setq evil-want-C-u-scroll t) + (setq evil-want-C-i-jump nil) + (setq evil-insert-state-cursor t) + :config + (evil-mode 1) + + ;; Fix keybindings. + (define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state) + (define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join) + + ;; Use visual line motions even outside of visual-line-mode buffers. + (evil-global-set-key 'motion "j" 'evil-next-visual-line) + (evil-global-set-key 'motion "k" 'evil-previous-visual-line) + + ;; Ensure some buffers start in normal mode. + (evil-set-initial-state 'messages-buffer-mode 'normal) + (evil-set-initial-state 'dashboard-mode 'normal)) + +(use-package evil-collection + :after evil + :config + (evil-collection-init)) + +(use-package evil-nerd-commenter + :bind ("M-/" . evilnc-comment-or-uncomment-lines)) + +(provide 'td-evil) diff --git a/lisp/td-functions.el b/lisp/td-functions.el new file mode 100644 index 0000000..4475037 --- /dev/null +++ b/lisp/td-functions.el @@ -0,0 +1,64 @@ +;;; -*- lexical-binding: t; -*- + +(defun td/display-startup-time () + (message (if (daemonp) + "emacs daemon loaded in %s with %d garbage collections." + "emacs loaded in %s with %d garbage collections.") + (format "%.2f seconds" + (float-time + (time-subtract after-init-time before-init-time))) + gcs-done)) + +(defun td/set-font () + (when (display-graphic-p) + (message "Setting font...") + (set-face-attribute 'default nil + :font "Iosevka Comfy Motion Fixed" + :weight 'normal + :height 200) + (set-face-attribute 'fixed-pitch nil + :font "Iosevka Comfy Motion Fixed" + :weight 'normal + :height 200) + (set-face-attribute 'variable-pitch nil + :font "Iosevka Comfy Motion Fixed" + :weight 'normal + :height 200))) + +(defun td/increment-number-at-point (&optional increment) + "Increment number at point like vim's `C-a'." + (interactive "p") + (td/change-number-at-point '+ (or increment 2))) + +(defun td/decrement-number-at-point (&optional decrement) + "Decrement number at point like vim's `C-x'." + (interactive "p") + (td/change-number-at-point '- (or decrement 2))) + +(defun td/change-number-at-point (change operation) + "The generic logic for incrementing and decrementing numbers at point." + (search-forward-regexp (rx digit)) + (let ((number (number-at-point)) + (point (point))) + (when number + (forward-word) + (search-backward (number-to-string number)) + (replace-match (number-to-string (funcall change number operation))) + (goto-char (- point 1))))) + +(defun td/disable-theme () + "Disable all themes." + (interactive) + (dolist (theme custom-enabled-themes) + (disable-theme theme))) + +(defun td/toggle-theme () + "Toggle between light and dark modes." + (interactive) + (let ((theme (if (eq (car custom-enabled-themes) 'ef-dark) + 'ef-day + 'ef-dark))) + (td/disable-theme) + (load-theme theme t))) + +(provide 'td-functions) diff --git a/lisp/td-mu4e.el b/lisp/td-mu4e.el new file mode 100644 index 0000000..6e45fbb --- /dev/null +++ b/lisp/td-mu4e.el @@ -0,0 +1,63 @@ +;;; -*- lexical-binding: t; -*- + +(use-package mu4e + :ensure nil + :bind (("C-c m m" . mu4e) + ("C-c m c" . 'mu4e-compose-new) + ("C-c m u" . 'mu4e-update-mail-and-index)) + :config + (setq mu4e-maildir "~/Mail") + + ;; IMAP options. + (setq mu4e-update-interval (* 5 60)) + (setq mu4e-get-mail-command "mbsync -a") + (setq mu4e-change-filenames-when-moving t) + + ;; SMTP options. + (setq message-send-mail-function 'message-send-mail-with-sendmail) + (setq sendmail-program "/etc/profiles/per-user/tdback/bin/msmtp") + + ;; Compose options. + (setq mu4e-compose-format-flowed t) + (setq mu4e-compose-dont-reply-to-self t) + (setq message-kill-buffer-on-exit t) + + ;; Display options. + (setq mu4e-view-show-images t) + (setq mu4e-view-show-addresses t) + (setq mu4e-modeline-show-global nil) + + (setq mu4e-contexts + (list + ;; Personal account. + (make-mu4e-context + :name "Personal" + :vars '((user-mail-address . "tyler@tdback.net") + (user-full-name . "Tyler Dunneback") + (mu4e-compose-signature . "Tyler Dunneback") + (mu4e-drafts-folder . "/tdback/Drafts") + (mu4e-sent-folder . "/tdback/Sent") + (mu4e-refile-folder . "/tdback/Archive") + (mu4e-trash-folder . "/tdback/Trash"))))) + + (setq mu4e-maildir-shortcuts + '(("/tdback/Inbox" . ?i) + ("/tdback/Sent" . ?s) + ("/tdback/Trash" . ?t) + ("/tdback/Drafts" . ?d) + ("/tdback/Archive" . ?a) + ("/tdback/All Mail" . ?m)))) + +(use-package org-mime + :ensure t + :config + (setq org-mime-export-options (list :section-numbers nil + :with-author nil + :with-toc nil)) + (add-hook 'org-mime-html-hook (lambda () + (org-mime-change-element-style + "pre" (format "color: %s; background-color: %s; padding: 0.5em;" + "#E6E1DC" "#232323")))) + (add-hook 'message-send-hook 'org-mime-confirm-when-no-multipart)) + +(provide 'td-mu4e) diff --git a/lisp/td-org.el b/lisp/td-org.el new file mode 100644 index 0000000..d9ca50e --- /dev/null +++ b/lisp/td-org.el @@ -0,0 +1,172 @@ +;;; -*- lexical-binding: t; -*- + +;;; ----- Bootstrapping Functions ----- + +(defun td/org-font-setup () + (font-lock-add-keywords 'org-mode + '(("^ *\\([-]\\) " + (0 (prog1 () + (compose-region (match-beginning 1) + (match-end 1) + "•")))))) + (dolist (face '((org-level-1 . 1.2) + (org-level-2 . 1.15) + (org-level-3 . 1.1) + (org-level-4 . 1.0))) + (set-face-attribute (car face) + nil + :font "Iosevka Comfy Motion Fixed" + :weight 'regular + :height (cdr face))) + (set-face-attribute 'org-block + nil + :foreground nil + :inherit 'fixed-pitch) + (set-face-attribute 'org-code + nil + :foreground nil + :inherit '(shadow fixed-pitch)) + (set-face-attribute 'org-table + nil + :foreground nil + :inherit '(shadow fixed-pitch)) + (set-face-attribute 'org-verbatim + nil + :foreground nil + :inherit '(shadow fixed-pitch)) + (set-face-attribute 'org-special-keyword + nil + :foreground nil + :inherit '(font-lock-comment-face fixed-pitch)) + (set-face-attribute 'org-meta-line + nil + :foreground nil + :inherit '(font-lock-comment-face fixed-pitch)) + (set-face-attribute 'org-checkbox + nil + :inherit 'fixed-pitch)) + +(defun td/org-mode-setup () + (org-indent-mode) + (variable-pitch-mode 1) + (visual-line-mode 1) + (setq evil-auto-indent nil)) + +;;; ----- Package Declaration ----- + +(use-package org + :ensure t + :hook (org-mode . td/org-mode-setup) + :bind (("C-c c" . org-capture) + ("C-c a" . org-agenda)) + :config + (setq org-ellipsis " ▾" + org-hide-emphasis-markers t + org-agenda-start-with-log-mode t + org-log-done 'time + org-fontify-whole-heading-line t + org-fontify-quote-and-verse-blocks t + org-src-tab-acts-natively t + org-edit-src-content-indentation 2 + org-hide-block-startup nil + org-log-into-drawer t + org-agenda-files '("~/Documents/org/tasks.org" + "~/Documents/org/ideas.org") + org-agenda-custom-commands '(("d" "Dashboard" + ((agenda "" + ((org-deadline-warning-days 7))) + (todo "NEXT" + ((org-agenda-overriding-header "Next Tasks"))))) + ("n" "Next Tasks" + ((todo "NEXT" + ((org-agenda-overriding-header "Next Tasks"))))) + ("s" "Status" + (todo "ACTIVE" + ((org-agenda-overriding-header "In Progress") + (org-agenda-files org-agenda-files))) + ((todo "BACKLOG" + ((org-agenda-overriding-header "Backlog") + (org-agenda-todo-list-sublevels nil) + (org-agenda-files org-agenda-files))) + (todo "CANCELED" + ((org-agenda-overriding-header "Canceled") + (org-agenda-files org-agenda-files))) + (todo "COMPLETED" + ((org-agenda-overriding-header "Completed") + (org-agenda-files org-agenda-files))) + ((todo "PLAN" + ((org-agenda-overriding-header "In Planning") + (org-agenda-todo-list-sublevels nil) + (org-agenda-files org-agenda-files))) + (todo "READY" + ((org-agenda-overriding-header "Ready for Work") + (org-agenda-files org-agenda-files))))))) + org-capture-templates '(("t" "Tasks") + ("tt" "New Task" entry (file+olp (car org-agenda-files)) + "* TODO %?\n %i" :empty-lines 1) + ("i" "Ideas") + ("ii" "New Idea" entry (file+olp (cadr org-agenda-files)) + "* %^{Idea}\n %U\n %?\n %i" :empty-lines 1)) + org-todo-keywords '((sequence "TODO(t)" + "NEXT(n)" + "|" + "DONE(d!)") + (sequence "BACKLOG(b)" + "PLAN(p)" + "READY(r)" + "ACTIVE(a)" + "|" + "COMPLETED(c)" + "CANCELED(k@)")) + org-refile-targets '(("archive.org" :maxlevel . 1) + ("tasks.org" :maxlevel . 1))) + (advice-add 'org-refile :after 'org-save-all-org-buffers) + (td/org-font-setup)) + +(use-package org-appear + :ensure t + :after org + :custom + (org-hide-emphasis-markers t) + (org-appear-autolinks t) + (org-appear-inside-latex t) + (org-appear-autoentities t) + (org-appear-autosubmarkers t) + :config + (add-hook 'org-mode-hook 'org-appear-mode)) + +(use-package org-modern + :ensure t + :hook ((org-mode . org-modern-mode) + (org-agenda-finalize-hook . org-modern-agenda)) + :custom ((org-modern-todo t) + (org-modern-table nil) + (org-modern-variable-pitch nil) + (org-modern-block-fringe nil)) + :commands + (org-modern-mode org-modern-agenda) + :init + (global-org-modern-mode)) + +(use-package org-timeline + :ensure t + :commands org-agenda + :init + (add-hook 'org-agenda-finalize-hook 'org-timeline-insert-timeline :append)) + +;; Code block execution and template expansion. +(with-eval-after-load 'org + (org-babel-do-load-languages 'org-babel-load-languages + '((emacs-lisp . t) + (python . t))) + + (push '("conf-unix" . conf-unix) org-src-lang-modes) + + (require 'org-tempo) + (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 '("rs" . "src rust")) + (add-to-list 'org-structure-template-alist '("sh" . "src shell")) + (add-to-list 'org-structure-template-alist '("sq" . "src sqlite"))) + +(provide 'td-org) diff --git a/lisp/td-present.el b/lisp/td-present.el new file mode 100644 index 0000000..72cd901 --- /dev/null +++ b/lisp/td-present.el @@ -0,0 +1,27 @@ +;;; -*- lexical-binding: t; -*- + +(use-package org-present + :ensure t + :hook ((org-present-mode . td/org-present-start) + (org-present-mode-quit . td/org-present-end) + (org-present-after-navigate-functions . td/org-present-prepare-slide))) + +(defun td/org-present-start () + (setq-local face-remapping-alist + '((default (:height 1.5) variable-pitch) + (header-line (:height 4.0) variable-pitch) + (org-document-title (:height 1.75) org-document-title) + (org-code (:height 1.55) org-code) + (org-verbatim (:height 1.55) org-verbatim) + (org-block (:height 1.25) org-block) + (org-block-begin-line (:height 0.7) org-block)))) + +(defun td/org-present-end () + (setq-local face-remapping-alist '((default variable-pitch default)))) + +(defun td/org-present-prepare-slide (buffer-name heading) + (org-overview) + (org-show-entry) + (org-show-children)) + +(provide 'td-present) diff --git a/lisp/td-programming.el b/lisp/td-programming.el new file mode 100644 index 0000000..eee8d67 --- /dev/null +++ b/lisp/td-programming.el @@ -0,0 +1,123 @@ +;;; -*- lexical-binding: t; -*- + +;;; ----- Completion ----- + +(use-package cape + :defer 10 + :init + ;; Add `completion-at-point-functions', used by `completion-at-point'. + (add-to-list 'completion-at-point-functions #'cape-file) + ;; Nice completion to have available everywhere. + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + :config + ;; Silence then pcomplete capf, no errors or messages. + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) + ;; Ensure that pcomplete does not write to the buffer and behaves as a pure + ;; `completion-at-point-function'. + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify)) + +(use-package corfu + :ensure t + :custom + (corfu-cycle t) ; Cycle through candidates + (corfu-auto t) ; Enable auto completion. + (corfu-auto-prefix 2) ; Display completion options after two characters. + (corfu-auto-delay 0.0) ; Don't delay. + (corfu-quit-at-boundary 'separator) ; Quit if no separator has been inserted at the boundary. + (corfu-echo-documentation 0.25) ; Echo docs shortly after options. + (corfu-preview-current 'insert) ; Auto-insert the current completion. + (corfu-preselect-first nil) ; Don't select a completion right away. + :bind (:map corfu-map + ("M-SPC" . corfu-insert-separator) + ("C-n" . corfu-next) + ([tab] . corfu-next) + ("C-p" . corfu-previous) + ([backtab] . corfu-previous) + ("S-" . corfu-insert) + ("RET" . nil)) + :init + ;; Use corfu everywhere. + (global-corfu-mode) + ;; Save completion history for better sorting. + (corfu-history-mode)) + +(use-package eglot + :ensure t + :defer t + :config + (setq eglot-autoshutdown t + elgot-ignored-server-capabilities '(:inlayHintProvider)) + (add-to-list 'eglot-server-programs '(c-mode . ("clangd"))) + (add-to-list 'eglot-server-programs '(c++-mode . ("clangd"))) + (add-to-list 'eglot-server-programs '(nix-mode . ("nixd"))) + (add-to-list 'eglot-server-programs '(python-mode . ("pylsp"))) + (add-to-list 'eglot-server-programs '(rust-mode . ("rust-analyzer"))) + :hook + ((c-mode . eglot-ensure) + (c++-mode . eglot-ensure) + (nix-mode . eglot-ensure) + (python-mode . eglot-ensure) + (rust-mode . eglot-ensure))) + +(use-package orderless + :ensure t + :commands (orderless) + :custom + (completion-styles '(orderless flex))) + +;;; ----- Modes ----- + +(use-package dockerfile-mode + :ensure t + :defer t) + +(use-package markdown-mode + :ensure t + :defer t) + +(use-package nix-mode + :ensure t + :defer t) + +(use-package python-mode + :ensure t + :defer t) + +(use-package rust-mode + :ensure t + :defer t + :config + (setq rust-format-on-save nil)) + +(use-package toml-mode + :ensure t + :defer t) + +(use-package yaml-mode + :ensure t + :defer t) + +;;; ----- Tooling & Enhancements ----- + +(use-package compile + ;; Using `C-u' before recompile acts like `M-x compile'. + :bind (("C-x C-m" . recompile)) + :custom + (compilation-scroll-output t)) + +(use-package magit + :ensure t + :commands magit-status) + +(use-package paren-face + :ensure t + :hook ((prog-mode + eshell-mode + inferior-lisp-mode + inferior-emacs-lisp-mode + lisp-interaction-mode + sly-mrepl-mode + scheme-mode) + . paren-face-mode)) + +(provide 'td-programming) diff --git a/lisp/td-writing.el b/lisp/td-writing.el new file mode 100644 index 0000000..df9989f --- /dev/null +++ b/lisp/td-writing.el @@ -0,0 +1,22 @@ +;;; -*- lexical-binding: t; -*- + +(use-package jinx + :ensure t + :hook ((org-mode . jinx-mode) + (text-mode . jinx-mode)) + :bind (("M-$" . jinx-correct) + ("C-M-$" . jinx-languages))) + +(use-package olivetti + :ensure t + :defer t + :hook ((markdown-mode . olivetti-mode) + (org-mode . olivetti-mode)) + :init + (setq olivetti-body-width 80)) + +(use-package writegood-mode + :ensure t + :hook (jinx-mode . writegood-mode)) + +(provide 'td-writing) -- cgit v1.2.3