;;; init.el -*- lexical-binding: t; -*- (defun chris/display-startup-time () (message "Emacs loaded in %s with %d garbage collections." (format "%.2f seconds" (float-time (time-subtract after-init-time before-init-time))) gcs-done)) (add-hook 'emacs-startup-hook #'chris/display-startup-time) (setq inhibit-startup-message t) (scroll-bar-mode -1) (tool-bar-mode -1) (tooltip-mode -1) (set-fringe-mode +1) (menu-bar-mode -1) (blink-cursor-mode -1) (column-number-mode +1) (setq-default indent-tabs-mode nil) (setq comp-deferred-compilation-deny-list nil) (setq frame-resize-pixelwise t) (if (string-equal (system-name) "syl") (defvar chris/default-font-size 120) (defvar chris/default-font-size 120)) (defun chris/set-font-faces () "Set the faces for our fonts" (message "Setting faces!") (set-face-attribute 'default nil :font "VictorMono Nerd Font" :height chris/default-font-size) (set-face-attribute 'fixed-pitch nil :font "VictorMono Nerd Font" :height chris/default-font-size) (set-face-attribute 'variable-pitch nil :font "Noto Sans" :height (+ chris/default-font-size (/ chris/default-font-size 12)) :weight 'regular)) (defun chris/set-transparency () "Set the frame to be transparent but not the text" (set-frame-parameter (selected-frame) 'alpha-background 100) (add-to-list 'default-frame-alist '(alpha-background . 100)) (add-to-list 'initial-frame-alist '(alpha-background . 100))) (if (daemonp) (add-hook 'after-make-frame-functions (lambda (frame) (with-selected-frame frame (chris/set-font-faces) (chris/set-transparency) (tool-bar-mode -1))) (chris/set-font-faces))) (setq display-line-numbers-type t) (global-display-line-numbers-mode +1) (add-hook 'prog-mode-hook (display-line-numbers-mode +1)) (global-visual-line-mode +1) (defun on-frame-open (frame) (if (not (display-graphic-p frame)) (set-face-background 'default "unspecified-bg" frame))) (add-hook 'after-make-frame-functions 'on-frame-open) ;; always avoid GUI (setq use-dialog-box nil) ;; Don't display floating tooltips; display their contents in the echo-area, ;; because native tooltips are ugly. (when (bound-and-true-p tooltip-mode) (tooltip-mode -1)) ;; ...especially on linux (setq x-gtk-use-system-tooltips nil) ;; Favor vertical splits over horizontal ones. Screens are usually wide. (setq split-width-threshold 160 split-height-threshold nil) (setq doc-view-resolution 192) (fset 'evil-redirect-digit-argument 'ignore) (global-set-key (kbd "") 'keyboard-escape-quit) (recentf-mode +1) (add-to-list 'exec-path "/home/chris/bin") (setq initial-major-mode 'org-mode) (setq initial-scratch-message "#+TITLE: SCRATCH\n#+DESCRIPTION: This buffer is for temporary things") (dolist (path load-path) (when (string-match-p "/nix/store/[a-z0-9]\\{32\\}-emacs-packages-deps.*" path) (dolist (autoload-file (directory-files path t "-autoloads.el")) (with-demoted-errors "init.el error: %s" (load autoload-file nil t))))) (eval-when-compile (require 'use-package)) (setq use-package-verbose t) (defalias 'yes-or-no-p 'y-or-n-p) (use-package command-log-mode :commands command-log-mode) (use-package all-the-icons) (use-package doom-modeline :ensure t :init (doom-modeline-mode 1) (setq doom-modeline-height 25 doom-modeline-bar-width 3 all-the-icons-scale-factor 0.9 doom-modeline-hud nil doom-modeline-buffer-file-name-style 'file-name doom-modeline-buffer-encoding nil doom-modeline-mu4e t doom-modeline-enable-word-count nil) (if (daemonp) (add-hook 'after-make-frame-functions (lambda (frame) (with-selected-frame frame (setq doom-modeline-icon t)))))) (use-package doom-themes :ensure t :init (load-theme 'doom-snazzy t)) (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) (use-package smartparens :defer 1 :config (smartparens-global-mode +1)) (use-package aggressive-indent :defer 1 :config (aggressive-indent-mode -1)) (use-package adaptive-wrap :defer t) (use-package which-key :config (setq which-key-idle-delay 0.3) (which-key-mode) :defer 1) (setenv "WAYLAND_DISPLAY" (if (string= (getenv "XDG_CURRENT_DESKTOP") "Hyprland") "wayland-1" "wayland-0")) (executable-find "ssh") (setq ispell-program-name "hunspell" ispell-local-dictionary "en_US" ispell-local-dictionary-alist ;; Please note the list `("-d" "en_US")` contains ACTUAL parameters passed to hunspell ;; You could use `("-d" "en_US,en_US-med")` to check with multiple dictionaries '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8))) (add-hook 'org-mode-hook 'chris/org-mode-setup) (use-package no-littering) ;; no-littering doesn't set this by default so we must place ;; auto save files in the same path as it uses for sessions (setq auto-save-file-name-transforms `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))) (let ((alist '((?! . "\\(?:!\\(?:==\\|[!=]\\)\\)") (?# . "\\(?:#\\(?:###?\\|_(\\|[!#(:=?[_{]\\)\\)") (?$ . "\\(?:\\$>\\)") (?& . "\\(?:&&&?\\)") (?* . "\\(?:\\*\\(?:\\*\\*\\|[/>]\\)\\)") (?+ . "\\(?:\\+\\(?:\\+\\+\\|[+>]\\)\\)") (?- . "\\(?:-\\(?:-[>-]\\|<<\\|>>\\|[<>|~-]\\)\\)") (?. . "\\(?:\\.\\(?:\\.[.<]\\|[.=?-]\\)\\)") (?/ . "\\(?:/\\(?:\\*\\*\\|//\\|==\\|[*/=>]\\)\\)") (?: . "\\(?::\\(?:::\\|\\?>\\|[:<-?]\\)\\)") (?\; . "\\(?:;;\\)") (?< . "\\(?:<\\(?:!--\\|\\$>\\|\\*>\\|\\+>\\|-[<>|]\\|/>\\|<[<=-]\\|=\\(?:=>\\|[<=>|]\\)\\||\\(?:||::=\\|[>|]\\)\\|~[>~]\\|[$*+/:<=>|~-]\\)\\)") (?= . "\\(?:=\\(?:!=\\|/=\\|:=\\|=[=>]\\|>>\\|[=>]\\)\\)") (?> . "\\(?:>\\(?:=>\\|>[=>-]\\|[]:=-]\\)\\)") (?? . "\\(?:\\?[.:=?]\\)") (?\[ . "\\(?:\\[\\(?:||]\\|[<|]\\)\\)") (?\ . "\\(?:\\\\/?\\)") (?\] . "\\(?:]#\\)") (?^ . "\\(?:\\^=\\)") (?_ . "\\(?:_\\(?:|?_\\)\\)") (?{ . "\\(?:{|\\)") (?| . "\\(?:|\\(?:->\\|=>\\||\\(?:|>\\|[=>-]\\)\\|[]=>|}-]\\)\\)") (?~ . "\\(?:~\\(?:~>\\|[=>@~-]\\)\\)")))) (dolist (char-regexp alist) (set-char-table-range composition-function-table (car char-regexp) `([,(cdr char-regexp) 0 font-shape-gstring])))) (use-package evil :init (setq evil-want-integration t evil-want-keybinding nil evil-want-C-i-jump nil evil-want-C-u-scroll t evil-respect-visual-line-mode t evil-want-C-u-delete t evil-undo-system 'undo-redo scroll-conservatively 101 hscroll-margin 2 scroll-margin 0 scroll-preserve-screen-position t hscroll-step 1 evil-vsplit-window-right t) :config (evil-mode +1)) (use-package evil-collection :after evil :config (evil-collection-init)) (use-package general :init (general-evil-setup) :config (defun chris/edit-emacs-config () "open the emacs config to edit" (interactive) (find-file (expand-file-name "README.org" user-emacs-directory))) (defun chris/open-bible () "find a bible to open" (interactive) (find-file "~/org/bibles/")) (general-create-definer chris/leader-keys :keymaps '(normal visual emacs) :prefix "SPC") (chris/leader-keys :states 'normal :keymaps 'override "b" '(:ignore t :which-key "buffer") "t" '(:ignore t :which-key "toggle") "f" '(:ignore t :which-key "file") "w" '(:ignore t :which-key "window") "s" '(:ignore t :which-key "search") "i" '(:ignore t :which-key "insert") "o" '(:ignore t :which-key "open") "oa" '(:ignore t :which-key "org agenda") "of" '(:ignore t :which-key "elfeed") "h" '(:ignore t :which-key "help") "n" '(:ignore t :which-key "notes") "m" '(:ignore t :which-key "music") "l" '(:ignore t :which-key "lsp") "sp" '(:ignore t :which-key "passwords") "bs" '(consult-buffer :which-key "buffer search") "bd" '(kill-this-buffer :which-key "kill buffer") "bi" '(ibuffer :which-key "ibuffer") "tt" '(consult-theme :which-key "choose theme") "tl" '(toggle-truncate-lines :which-key "truncate lines") "ts" '(ispell :which-key "spell check") "ff" '(find-file :which-key "find file") "fb" '(chris/open-bible :which-key "find bible book") "fr" '(consult-recent-file :which-key "recent file") "fs" '(save-buffer :which-key "save") "fE" '(consult-file-externally :which-key "find file externally") "fe" '(chris/edit-emacs-config :which-key "open config") "hf" '(helpful-callable :which-key "describe-function") "hv" '(helpful-variable :which-key "describe-variable") "hk" '(helpful-key :which-key "describe-key") "hF" '(describe-face :which-key "describe-face") "hb" '(general-describe-keybindings :which-key "describe-bindings") "hi" '(info :which-key "info manual") "ht" '(which-key-show-top-level :which-key "show top-level keybindings") "ss" '(consult-line :which-key "consult search") "sr" '(consult-ripgrep :which-key "consult ripgrep") "sd" '(dictionary-search :which-key "search the dictionary") "sv" '(imenu :which-key "imenu") "oP" '(proced :which-key "proced") "ov" '(vterm :which-key "vterm") "wo" '(other-window :which-key "other window") "wd" '(delete-window :which-key "other window") "wv" '(evil-window-vsplit :which-key "split window vertically") "ws" '(evil-window-split :which-key "split window horizontally") "wj" '(evil-window-down :which-key "down window") "wk" '(evil-window-up :which-key "up window") "wh" '(evil-window-left :which-key "left window") "wl" '(evil-window-right :which-key "right window") "wH" '(evil-window-move-far-left :which-key "right window") "wK" '(evil-window-move-very-top :which-key "right window") "wJ" '(evil-window-move-very-bottom :which-key "right window") "wL" '(evil-window-move-far-right :which-key "right window") ";" '(execute-extended-command :which-key "execute command") ":" '(eval-expression :which-key "evaluate expression")) (general-def 'minibuffer-local-map "C-v" 'evil-paste-after) (general-def 'normal "gcc" 'comment-line "K" 'helpful-at-point "C-+" 'text-scale-increase "C-_" 'text-scale-decrease "C-S-l" 'evil-window-increase-width "C-S-j" 'evil-window-decrease-height "C-S-k" 'evil-window-increase-height "C-S-h" 'evil-window-decrease-width "zi" 'text-scale-increase "zd" 'text-scale-decrease) (general-def 'normal Info-mode-map "RET" 'Info-follow-nearest-node "p" 'Info-prev "n" 'Info-next) (general-def 'normal prog-mode-map :states 'normal :keymaps 'override "go" 'ff-find-other-file "TAB" 'indent-according-to-mode) (general-def 'visual prog-mode-map :states 'visual :keymaps 'override "TAB" 'indent-region) (general-def 'insert prog-mode-map :states 'insert :keymaps 'override "TAB" 'indent-according-to-mode)) (use-package evil-escape :after evil :init (evil-escape-mode +1) :config (setq evil-escape-key-sequence (kbd "fd") evil-escape-delay 0.3)) (use-package evil-surround :after evil :config (global-evil-surround-mode +1)) (setq lpr-command "lpr -o sides=two-sided-long-edge -# ") (defun chris/org-mode-setup () (interactive) (org-indent-mode +1) (toc-org-mode +1) (visual-fill-column-mode +1) (display-line-numbers-mode -1) (variable-pitch-mode +1) (flyspell-mode +1) (setq visual-fill-column-width 100 visual-fill-column-center-text t) ;;Let's make sure org-mode faces are inheriting fixed pitch faces. (dolist (face '(org-block org-block-begin-line org-block-end-line org-code org-document-info-keyword org-meta-line org-table org-date org-verbatim)) (set-face-attribute `,face nil :inherit 'fixed-pitch)) ;; changing height and boldness (dolist (face '((org-level-1 1.4 ultra-bold) (org-level-2 1.2 extra-bold) (org-level-3 1.1 bold) (org-level-4 1.0 semi-bold) (org-level-5 1.0 normal) (org-column 1.0 normal))) (set-face-attribute (nth 0 face) nil :weight (nth 2 face) :height (nth 1 face))) ;; changing colors (dolist (face '((outline-2 "#5af78e") (outline-3 "#ffb86c") (outline-4 "#f3f99d"))) (set-face-attribute (nth 0 face) nil :foreground (nth 1 face))) (set-face-attribute 'org-block-end-line nil :inherit 'org-block-begin-line) (set-face-attribute 'org-column nil :background "#242631" :inherit 'fixed-pitch) (set-face-attribute 'org-quote nil :background "#242631" :inherit 'fixed-pitch)) (defun chris/org-convert-csv-table (beg end) (interactive (list (mark) (point))) (org-table-convert-region beg end ",")) (defun chris/org-cycle-hide-drawers (state) "Re-hide all drawers after a visibility state change." (interactive) (when (and (derived-mode-p 'org-mode) (not (memq state '(overview folded contents)))) (save-excursion (let* ((globalp (memq state '(contents all))) (beg (if globalp (point-min) (point))) (end (if globalp (point-max) (if (eq state 'children) (save-excursion (outline-next-heading) (point)) (org-end-of-subtree t))))) (goto-char beg) (while (re-search-forward org-drawer-regexp end t) (save-excursion (beginning-of-line 1) (when (looking-at org-drawer-regexp) (let* ((start (1- (match-beginning 0))) (limit (save-excursion (outline-next-heading) (point))) (msg (format (concat "org-cycle-hide-drawers: " "`:END:`" " line missing at position %s") (1+ start)))) (if (re-search-forward "^[ \t]*:END:" limit t) (outline-flag-region start (point-at-eol) t) (user-error msg)))))))))) (defun chris/org-agenda-setup () (interactive) (org-indent-mode +1) (toc-org-mode +1) (visual-fill-column-mode +1) (display-line-numbers-mode -1) (variable-pitch-mode -1) (toggle-truncate-lines +1) (evil-normal-state) (setq visual-fill-column-width 120 visual-fill-column-center-text t)) (defun chris/org-mpv (&optional url) (interactive) (if (string-empty-p url) (let (url url-get-url-at-point) (bongo-insert-uri url (format "%s ==> %s" title url))) (bongo-insert-uri url (format "%s ==> %s" title url)))) (defun chris/bible-imenu () "This is a special call on consult-imenu that will utilize orderless with a better dispatcher so that we can find our verses much faster. The hope is to also make this a faster version of imenu." (interactive) (consult-imenu)) (use-package org :defer 1 :config (setq org-startup-indented t org-edit-src-content-indentation 0 org-agenda-sticky t org-fontify-quote-and-verse-blocks t org-src-preserve-indentation t org-src-window-setup 'other-window org-export-with-broken-links t org-agenda-current-time-string "⭠ now ────────────────" org-log-into-drawer t org-latex-active-timestamp-format "\\textit{%s}" org-enforce-todo-dependencies t org-export-preserve-breaks t) (add-hook 'org-mode-hook 'chris/org-mode-setup) (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (python . t) (ditaa . t) (shell . t))) (setq org-ditaa-jar-path "/usr/bin/ditaa") (require 'org-tempo) (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) (add-to-list 'org-structure-template-alist '("cl" . "src common-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 '("yaml" . "src yaml")) (add-to-list 'org-structure-template-alist '("yml" . "src yaml")) (add-to-list 'org-structure-template-alist '("q" . "quote")) (add-to-list 'org-structure-template-alist '("rc" . "src restclient")) (setq org-capture-templates '(("t" "Personal todo" entry (file "todo/todo.org") (file ".templates/tasks.org") :prepend t) ("n" "Personal notes" entry (file "todo/notes.org") "* %u %?\n%i\n%a" :prepend t) ("j" "Journal" entry (file+olp+datetree +org-capture-journal-file) "* %U %?\n%i\n%a" :prepend t) ("p" "TFC Plan" entry (function chris/org-roam-capture-lesson-file) (file ".templates/tfcplantemplate.org") :prepend nil :jump-to-captured t :empty-lines 1) ("P" "TFC Posts" entry (file+headline "nvtfc_social_media.org" "Posts") (file ".templates/posts.org") :prepend t :jump-to-captured t) ("s" "TFC Supporter" entry (file "tfc_supporters.org") (file ".templates/supporter.org") :prepend t :jump-to-captured t) ("r" "Templates for projects") ("rt" "Project-local todo" entry (file+headline chris/project-todo "Tasks") "* TODO %?\n%a\n%i\n\n" :prepend t) ("rn" "Project-local notes" entry (file+headline chris/project-todo "Notes") "* %U %?\n%a\n%i\n\n" :prepend t) ("rc" "Project-local changelog" entry (file+headline chris/project-changelog "Changelog") "* %U %?\n%a\n%i\n\n" :prepend t)) org-capture-use-agenda-date t org-agenda-timegrid-use-ampm t org-agenda-show-inherited-tags nil org-agenda-tags-column -100) (setq org-agenda-prefix-format '((agenda . " %i %?-12t% s") (todo . " %i %-12:c") (tags . " %i %-12:c") (search . " %i %-12:c"))) (setq org-agenda-category-icon-alist '(("todo" "~/org/icons/task.png" nil nil :ascent center) ("lesson" "~/org/icons/book.png" nil nil :ascent center) ("dev" "~/org/icons/coding.png" nil nil :ascent center) ("TODO" "~/org/icons/coding.png" nil nil :ascent center))) (setq org-imenu-depth 4 org-odt-styles-file "/home/chris/org/style.odt" org-export-with-toc nil org-export-with-author nil org-todo-keywords '((sequence "TODO(t)" "PROJ(p)" "STRT(s)" "WAIT(w)" "HOLD(h)" "|" "DONE(d)" "CNCL(c)") (sequence "[ ](T)" "[-](S)" "[?](W)" "|" "[X](D)")) org-agenda-files '("/home/chris/org/todo/notes.org" "/home/chris/org/repetition.org" "/home/chris/org/tfc_plans.org" "/home/chris/org/ministry_team.org" "/home/chris/org/todo/todo.org" "/home/chris/org/newsletter.org" "/home/chris/org/archive.org" "/home/chris/org/nvtfc_social_media.org" "/home/chris/dev/church-presenter/TODO.org" "/home/chris/org/lessons/") org-id-method 'ts org-agenda-tags-column -75 org-columns-summary-types '(("+" . org-columns--summary-sum) ("$" . org-columns--summary-currencies) ("X" . org-columns--summary-checkbox) ("X/" . org-columns--summary-checkbox-count) ("X%" . org-columns--summary-checkbox-percent) ("max" . org-columns--summary-max) ("mean" . org-columns--summary-mean) ("min" . org-columns--summary-min) (":" . org-columns--summary-sum-times) (":max" . org-columns--summary-max-time) (":mean" . org-columns--summary-mean-time) (":min" . org-columns--summary-min-time) ("@max" . org-columns--summary-max-age) ("@mean" . org-columns--summary-mean-age) ("@min" . org-columns--summary-min-age) ("est+" . org-columns--summary-estimate))) (defun chris/org-columns-view () "Turn on org-columns overlay and turn off olivetti-mode" (interactive) (goto-char (point-min)) (org-content) (org-columns) (setq visual-fill-column-width 150)) (defun chris/org-columns-quit () "Remove the org-columns overlay and turn on olivetti-mode" (interactive) (org-columns-quit) (chris/org-mode-setup)) ;; (add-hook 'org-agenda-finalize-hook 'evil-normal-state) (add-hook 'org-agenda-finalize-hook 'chris/org-agenda-setup) (advice-add 'org-agenda-todo :after #'org-save-all-org-buffers) (setq org-refile-targets '((org-agenda-files . (:maxlevel . 6)))) (setq org-agenda-window-setup 'current-window) (defun chris/org-agenda () "create a window that houses my org-agenda" (interactive) (with-selected-frame (make-frame '((name . "org-agenda") (width . 100))) (org-agenda-list))) (setq org-latex-packages-alist '(("margin=2cm" "geometry" nil))) :general (chris/leader-keys :states 'normal :keymaps 'override "c" 'org-capture "rr" 'org-refile "E" 'org-export-dispatch "oa" 'org-agenda-list "gt" 'org-babel-tangle "il" 'org-insert-link "it" 'org-insert-todo-subheading) (chris/leader-keys :states 'normal :keymaps 'org-mode-map "is" 'org-time-stamp "tp" (chris/org-cycle-hide-drawers 'children)) (chris/leader-keys :states 'visual :keymaps 'override "il" 'org-insert-link) ('normal org-agenda-mode-map "q" 'org-agenda-quit "r" 'org-agenda-redo "d" 'org-agenda-deadline "s" 'org-agenda-schedule "t" 'org-agenda-todo "c" 'org-agenda-capture) ('normal org-columns-map "j" 'outline-next-heading "h" 'outline-previous-heading "q" 'chris/org-columns-quit) ('normal org-mode-map "RET" '+org/dwim-at-point "gC" 'chris/org-columns-view "ge" 'org-edit-src-code "gr" 'revert-buffer "ze" 'org-emphasize "zn" 'org-narrow-to-subtree "zw" 'widen "zp" 'org-set-property "zh" (chris/org-cycle-hide-drawers 'subtree) "S" 'org-schedule "t" 'org-todo "gf" 'org-footnote-action "gl" 'org-id-copy "gk" 'languagetool-correct-at-point) ('visual org-mode-map "gf" 'org-footnote-action) ('insert org-mode-map "C-i" 'completion-at-point) ('normal 'org-src-mode-map "q" 'org-edit-src-abort)) (defun chris/org-roam-capture-lesson-file () "Function to return the lesson file that is needed for TFC plan capture and move to correct position for plan insertion" (interactive) ;; (unless org-roam-mode (org-roam-mode +1)) (let ((node (org-roam-node-read))) (org-roam-node-visit node) (goto-char (point-min)) (search-forward "PLAN"))) (defun chris/project-todo () (concat (projectile-project-root) "TODO.org")) (defun chris/project-changelog () (concat (projectile-project-root) "CHANGELOG.org")) (defun chris/org-babel-tangle-config () (when (string-equal (buffer-file-name) (expand-file-name "README.org" user-emacs-directory)) (let ((org-confirm-babel-evaluate nil)) (org-babel-tangle)))) (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'chris/org-babel-tangle-config :append :local))) (use-package evil-org :ensure t :after org :hook (org-mode . (lambda () evil-org-mode)) :config ;; (add-to-list 'evil-digit-bound-motions 'evil-org-beginning-of-line) ;; (evil-define-key 'motion 'evil-org-mode ;; (kbd "0") 'evil-org-beginning-of-line) (require 'evil-org-agenda) (evil-org-agenda-set-keys)) (use-package org-super-agenda :after org :init (setq org-super-agenda-groups '((:name "📅 Today" :time-grid t :scheduled today) (:name "Due Today" :deadline today) (:name "Important" :priority "A") (:name "Development" :category "TODO" :category "dev") (:name "Overdue" :time-grid t :scheduled past :deadline past) (:name "Due soon" :deadline future))) :config (org-super-agenda-mode +1) (setq org-super-agenda-header-map nil)) (use-package org-roam :after org :ensure t :init (setq org-roam-v2-ack t) :config (setq org-roam-directory "~/org" org-roam-buffer-width 0.25 org-roam-file-exclude-regexp ".stversion.*\|.stfolder.*\|.*~.*\|.*sync.*" org-roam-db-location "~/.dotemacs/org-roam.db" org-roam-completion-everywhere t org-roam-capture-templates '(("d" "default" entry "\n* %?" :if-new (file+head "${slug}.org" "#+TITLE: ${title}\n#+AUTHOR: Chris Cochrun\n#+CREATED: %<%D - %I:%M %p>\n\n") :unnarrowed t) ("b" "bible" entry "\n* %?" :if-new (file+head "${slug}.org" "#+TITLE: ${title}\n#+AUTHOR: Chris Cochrun\n#+CREATED: %<%D - %I:%M %p>\n- tags :biblestudy:%^G\n\n") :unnarrowed t) ("l" "TFC Lesson" plain (file ".templates/lessontemplate.org") :if-new (file+head "lessons/${slug}.org" "#+TITLE: ${title}\n#+AUTHOR: Chris Cochrun\n#+CREATED: %<%D - %I:%M %p>\n") :unnarrowed t)) org-roam-dailies-capture-templates '(("d" "daily" plain "%?" :immediate-finish nil :file-name "%<%Y-%m-%d>" :head "#+TITLE: %<%Y-%m-%d>\n#+AUTHOR: Chris Cochrun\n#+CREATED: %<%D - %I:%M %p>\n\n* HFL\n* Tasks\n* Family\n** How Do I Love Abbie?" :target (file+head "%<%Y-%m-%d>.org" "#+TITLE: %<%Y-%m-%d>\n#+AUTHOR: Chris Cochrun\n#+CREATED: %<%D - %I:%M %p>\n\n* HFL\n* Tasks\n* Family\n** How Do I Love Abbie?\n* Bible") :unnarrowed t ) ("b" "biblical daily" plain "%?" :file-name "%<%Y-%m-%d>-bib" :target (file+head "%<%Y-%m-%d>-bib.org" "#+TITLE: %<%Y-%m-%d> - Biblical\n#+AUTHOR: Chris Cochrun\n#+CREATED: %<%D - %I:%M %p>\n\n* Notes") :unnarrowed t))) (defun chris/org-roam-node-create () "Create an org roam node underneath this org node" (interactive) (+org/insert-item-below 1) (org-id-get-create)) (defun chris/org-roam-node-id-create () "Make the basic org node and org roam one by adding an id and creating an alias" (interactive) (org-id-get-create) (org-roam-alias-add)) ;; (set-face-attribute 'magit-section-highlight nil :inherit 'variable-pitch) (org-roam-setup) :general (chris/leader-keys :states 'normal :keymaps 'override "nf" '(org-roam-node-find :which-key "org roam ff") "nr" 'org-roam-buffer-toggle "ni" 'chris/org-roam-node-create "nl" 'org-roam-node-insert "nc" 'org-roam-capture "nt" 'org-roam-dailies-goto-today "ng" 'org-roam-graph "na" 'org-roam-alias-add "in" 'org-roam-node-insert "nA" 'chris/org-roam-node-id-create) (chris/leader-keys :states 'visual :keymaps 'override "in" 'org-roam-node-insert)) (use-package websocket) (use-package org-roam-ui :after org-roam :config (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)) (use-package org-present :commands org-present :config (add-hook 'org-present-mode-hook (lambda () (org-present-big) (org-present-hide-cursor))) (add-hook 'org-present-mode-quit-hook (lambda () (org-present-small) (org-present-show-cursor))) :general (chris/leader-keys 'normal "oo" 'org-present) ('normal org-present-mode-map "q" 'org-present-quit "j" 'org-present-next "k" 'org-present-prev )) (use-package org-modern :config (setq org-modern-timestamp nil org-modern-table nil) (custom-set-faces '(org-modern-tag ((t :background "#9aedfe" :foreground "#282a36"))) ) (global-org-modern-mode +1) ) ;;; lang/org/autoload/org.el -*- lexical-binding: t; -*- ;; ;;; Helpers (defun +org--toggle-inline-images-in-subtree (&optional beg end refresh) "Refresh inline image previews in the current heading/tree." (let* ((beg (or beg (if (org-before-first-heading-p) (save-excursion (point-min)) (save-excursion (org-back-to-heading) (point))))) (end (or end (if (org-before-first-heading-p) (save-excursion (org-next-visible-heading 1) (point)) (save-excursion (org-end-of-subtree) (point))))) (overlays (cl-remove-if-not (lambda (ov) (overlay-get ov 'org-image-overlay)) (ignore-errors (overlays-in beg end))))) (dolist (ov overlays nil) (delete-overlay ov) (setq org-inline-image-overlays (delete ov org-inline-image-overlays))) (when (or refresh (not overlays)) (org-display-inline-images t t beg end) t))) (defun +org--insert-item (direction) (let ((context (org-element-lineage (org-element-context) '(table table-row headline inlinetask item plain-list) t))) (pcase (org-element-type context) ;; Add a new list item (carrying over checkboxes if necessary) ((or `item `plain-list) (let ((orig-point (point))) ;; Position determines where org-insert-todo-heading and `org-insert-item' ;; insert the new list item. (if (eq direction 'above) (org-beginning-of-item) (end-of-line)) (let* ((ctx-item? (eq 'item (org-element-type context))) (ctx-cb (org-element-property :contents-begin context)) ;; Hack to handle edge case where the point is at the ;; beginning of the first item (beginning-of-list? (and (not ctx-item?) (= ctx-cb orig-point))) (item-context (if beginning-of-list? (org-element-context) context)) ;; Horrible hack to handle edge case where the ;; line of the bullet is empty (ictx-cb (org-element-property :contents-begin item-context)) (empty? (and (eq direction 'below) ;; in case contents-begin is nil, or contents-begin ;; equals the position end of the line, the item is ;; empty (or (not ictx-cb) (= ictx-cb (1+ (point)))))) (pre-insert-point (point))) ;; Insert dummy content, so that `org-insert-item' ;; inserts content below this item (when empty? (insert " ")) (org-insert-item (org-element-property :checkbox context)) ;; Remove dummy content (when empty? (delete-region pre-insert-point (1+ pre-insert-point)))))) ;; Add a new table row ((or `table `table-row) (pcase direction ('below (save-excursion (org-table-insert-row t)) (org-table-next-row)) ('above (save-excursion (org-shiftmetadown)) (+org/table-previous-row)))) ;; Otherwise, add a new heading, carrying over any todo state, if ;; necessary. (_ (let ((level (or (org-current-level) 1))) ;; I intentionally avoid `org-insert-heading' and the like because they ;; impose unpredictable whitespace rules depending on the cursor ;; position. It's simpler to express this command's responsibility at a ;; lower level than work around all the quirks in org's API. (pcase direction (`below (let (org-insert-heading-respect-content) (goto-char (line-end-position)) (org-end-of-subtree) (insert "\n" (make-string level ?*) " "))) (`above (org-back-to-heading) (insert (make-string level ?*) " ") (save-excursion (insert "\n")))) (run-hooks 'org-insert-heading-hook) (when-let* ((todo-keyword (org-element-property :todo-keyword context)) (todo-type (org-element-property :todo-type context))) (org-todo (cond ((eq todo-type 'done) ;; Doesn't make sense to create more "DONE" headings (car (+org-get-todo-keywords-for todo-keyword))) (todo-keyword) ('todo))))))) (when (org-invisible-p) (org-show-hidden-entry)) (when (and (bound-and-true-p evil-local-mode) (not (evil-emacs-state-p))) (evil-insert 1)))) ;;;###autoload (defun +org-get-todo-keywords-for (&optional keyword) "Returns the list of todo keywords that KEYWORD belongs to." (when keyword (cl-loop for (type . keyword-spec) in (cl-remove-if-not #'listp org-todo-keywords) for keywords = (mapcar (lambda (x) (if (string-match "^\\([^(]+\\)(" x) (match-string 1 x) x)) keyword-spec) if (eq type 'sequence) if (member keyword keywords) return keywords))) ;; ;;; Modes ;;;###autoload (define-minor-mode +org-pretty-mode "Hides emphasis markers and toggles pretty entities." :init-value nil :lighter " *" :group 'evil-org (setq org-hide-emphasis-markers +org-pretty-mode) (org-toggle-pretty-entities) (with-silent-modifications ;; In case the above un-align tables (org-table-map-tables 'org-table-align t))) ;; ;;; Commands ;;;###autoload (defun +org/return () "Call `org-return' then indent (if `electric-indent-mode' is on)." (interactive) (org-return electric-indent-mode)) ;;;###autoload (defun +org/dwim-at-point (&optional arg) "Do-what-I-mean at point. If on a: - checkbox list item or todo heading: toggle it. - citation: follow it - headline: cycle ARCHIVE subtrees, toggle latex fragments and inline images in subtree; update statistics cookies/checkboxes and ToCs. - clock: update its time. - footnote reference: jump to the footnote's definition - footnote definition: jump to the first reference of this footnote - timestamp: open an agenda view for the time-stamp date/range at point. - table-row or a TBLFM: recalculate the table's formulas - table-cell: clear it and go into insert mode. If this is a formula cell, recaluclate it instead. - babel-call: execute the source block - statistics-cookie: update it. - src block: execute it - latex fragment: toggle it. - link: follow it - otherwise, refresh all inline images in current tree." (interactive "P") (if (button-at (point)) (call-interactively #'push-button) (let* ((context (org-element-context)) (type (org-element-type context))) ;; skip over unimportant contexts (while (and context (memq type '(verbatim code bold italic underline strike-through subscript superscript))) (setq context (org-element-property :parent context) type (org-element-type context))) (pcase type ((or `citation `citation-reference) (org-cite-follow context arg)) (`headline (cond ((memq (bound-and-true-p org-goto-map) (current-active-maps)) (org-goto-ret)) ((and (fboundp 'toc-org-insert-toc) (member "TOC" (org-get-tags))) (toc-org-insert-toc) (message "Updating table of contents")) ((string= "ARCHIVE" (car-safe (org-get-tags))) (org-force-cycle-archived)) ((or (org-element-property :todo-type context) (org-element-property :scheduled context)) (org-todo (if (eq (org-element-property :todo-type context) 'done) (or (car (+org-get-todo-keywords-for (org-element-property :todo-keyword context))) 'todo) 'done)))) ;; Update any metadata or inline previews in this subtree (org-update-checkbox-count) (org-update-parent-todo-statistics) (when (and (fboundp 'toc-org-insert-toc) (member "TOC" (org-get-tags))) (toc-org-insert-toc) (message "Updating table of contents")) (let* ((beg (if (org-before-first-heading-p) (line-beginning-position) (save-excursion (org-back-to-heading) (point)))) (end (if (org-before-first-heading-p) (line-end-position) (save-excursion (org-end-of-subtree) (point)))) (overlays (ignore-errors (overlays-in beg end))) (latex-overlays (cl-find-if (lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay)) overlays)) (image-overlays (cl-find-if (lambda (o) (overlay-get o 'org-image-overlay)) overlays))) (+org--toggle-inline-images-in-subtree beg end) (if (or image-overlays latex-overlays) (org-clear-latex-preview beg end) (org--latex-preview-region beg end)))) (`clock (org-clock-update-time-maybe)) (`footnote-reference (org-footnote-goto-definition (org-element-property :label context))) (`footnote-definition (org-footnote-goto-previous-reference (org-element-property :label context))) ((or `planning `timestamp) (org-follow-timestamp-link)) ((or `table `table-row) (if (org-at-TBLFM-p) (org-table-calc-current-TBLFM) (ignore-errors (save-excursion (goto-char (org-element-property :contents-begin context)) (org-call-with-arg 'org-table-recalculate (or arg t)))))) (`table-cell (org-table-blank-field) (org-table-recalculate arg) (when (and (string-empty-p (string-trim (org-table-get-field))) (bound-and-true-p evil-local-mode)) (evil-change-state 'insert))) (`babel-call (org-babel-lob-execute-maybe)) (`statistics-cookie (save-excursion (org-update-statistics-cookies arg))) ((or `src-block `inline-src-block) (org-babel-execute-src-block arg)) ((or `latex-fragment `latex-environment) (org-latex-preview arg)) (`link (let* ((lineage (org-element-lineage context '(link) t)) (path (org-element-property :path lineage))) (if (or (equal (org-element-property :type lineage) "img") (and path (image-type-from-file-name path))) (+org--toggle-inline-images-in-subtree (org-element-property :begin lineage) (org-element-property :end lineage)) (org-open-at-point arg)))) (`paragraph (+org--toggle-inline-images-in-subtree)) ((guard (org-element-property :checkbox (org-element-lineage context '(item) t))) (let ((match (and (org-at-item-checkbox-p) (match-string 1)))) (org-toggle-checkbox (if (equal match "[ ]") '(16))))) (_ (if (or (org-in-regexp org-ts-regexp-both nil t) (org-in-regexp org-tsr-regexp-both nil t) (org-in-regexp org-link-any-re nil t)) (call-interactively #'org-open-at-point) (+org--toggle-inline-images-in-subtree (org-element-property :begin context) (org-element-property :end context)))))))) ;;;###autoload (defun +org/shift-return (&optional arg) "Insert a literal newline, or dwim in tables. Executes `org-table-copy-down' if in table." (interactive "p") (if (org-at-table-p) (org-table-copy-down arg) (org-return nil arg))) ;; I use these instead of `org-insert-item' or `org-insert-heading' because they ;; impose bizarre whitespace rules depending on cursor location and many ;; settings. These commands have a much simpler responsibility. ;;;###autoload (defun +org/insert-item-below (count) "Inserts a new heading, table cell or item below the current one." (interactive "p") (dotimes (_ count) (+org--insert-item 'below))) ;;;###autoload (defun +org/insert-item-above (count) "Inserts a new heading, table cell or item above the current one." (interactive "p") (dotimes (_ count) (+org--insert-item 'above))) ;;;###autoload (defun +org/toggle-last-clock (arg) "Toggles last clocked item. Clock out if an active clock is running (or cancel it if prefix ARG is non-nil). If no clock is active, then clock into the last item. See `org-clock-in-last' to see how ARG affects this command." (interactive "P") (require 'org-clock) (cond ((org-clocking-p) (if arg (org-clock-cancel) (org-clock-out))) ((and (null org-clock-history) (or (org-on-heading-p) (org-at-item-p)) (y-or-n-p "No active clock. Clock in on current item?")) (org-clock-in)) ((org-clock-in-last arg)))) ;;; Folds ;;;###autoload (defalias #'+org/toggle-fold #'+org-cycle-only-current-subtree-h) ;;;###autoload (defun +org/open-fold () "Open the current fold (not but its children)." (interactive) (+org/toggle-fold t)) ;;;###autoload (defalias #'+org/close-fold #'outline-hide-subtree) ;;;###autoload (defun +org/close-all-folds (&optional level) "Close all folds in the buffer (or below LEVEL)." (interactive "p") (outline-hide-sublevels (or level 1))) ;;;###autoload (defun +org/open-all-folds (&optional level) "Open all folds in the buffer (or up to LEVEL)." (interactive "P") (if (integerp level) (outline-hide-sublevels level) (outline-show-all))) (defun +org--get-foldlevel () (let ((max 1)) (save-restriction (narrow-to-region (window-start) (window-end)) (save-excursion (goto-char (point-min)) (while (not (eobp)) (org-next-visible-heading 1) (when (outline-invisible-p (line-end-position)) (let ((level (org-outline-level))) (when (> level max) (setq max level)))))) max))) ;;;###autoload (defun +org/show-next-fold-level (&optional count) "Decrease the fold-level of the visible area of the buffer. This unfolds another level of headings on each invocation." (interactive "p") (let ((new-level (+ (+org--get-foldlevel) (or count 1)))) (outline-hide-sublevels new-level) (message "Folded to level %s" new-level))) ;;;###autoload (defun +org/hide-next-fold-level (&optional count) "Increase the global fold-level of the visible area of the buffer. This folds another level of headings on each invocation." (interactive "p") (let ((new-level (max 1 (- (+org--get-foldlevel) (or count 1))))) (outline-hide-sublevels new-level) (message "Folded to level %s" new-level))) ;; ;;; Hooks ;;;###autoload (defun +org-indent-maybe-h () "Indent the current item (header or item), if possible. Made for `org-tab-first-hook' in evil-mode." (interactive) (cond ((not (and (bound-and-true-p evil-local-mode) (evil-insert-state-p))) nil) ((and (bound-and-true-p org-cdlatex-mode) (or (org-inside-LaTeX-fragment-p) (org-inside-latex-macro-p))) nil) ((org-at-item-p) (if (eq this-command 'org-shifttab) (org-outdent-item-tree) (org-indent-item-tree)) t) ((org-at-heading-p) (ignore-errors (if (eq this-command 'org-shifttab) (org-promote) (org-demote))) t) ((org-in-src-block-p t) (save-window-excursion (org-babel-do-in-edit-buffer (call-interactively #'indent-for-tab-command))) t) ((and (save-excursion (skip-chars-backward " \t") (bolp)) (org-in-subtree-not-table-p)) (call-interactively #'tab-to-tab-stop) t))) ;;;###autoload (defun +org-cycle-only-current-subtree-h (&optional arg) "Toggle the local fold at the point, and no deeper. `org-cycle's standard behavior is to cycle between three levels: collapsed, subtree and whole document. This is slow, especially in larger org buffer. Most of the time I just want to peek into the current subtree -- at most, expand *only* the current subtree. All my (performant) foldings needs are met between this and `org-show-subtree' (on zO for evil users), and `org-cycle' on shift-TAB if I need it." (interactive "P") (unless (or (eq this-command 'org-shifttab) (and (bound-and-true-p org-cdlatex-mode) (or (org-inside-LaTeX-fragment-p) (org-inside-latex-macro-p)))) (save-excursion (org-beginning-of-line) (let (invisible-p) (when (and (org-at-heading-p) (or org-cycle-open-archived-trees (not (member org-archive-tag (org-get-tags)))) (or (not arg) (setq invisible-p (outline-invisible-p (line-end-position))))) (unless invisible-p (setq org-cycle-subtree-status 'subtree)) (org-cycle-internal-local) t))))) ;;;###autoload (defun +org-make-last-point-visible-h () "Unfold subtree around point if saveplace places us in a folded region." (and (not org-inhibit-startup) (not org-inhibit-startup-visibility-stuff) ;; Must be done on a timer because `org-show-set-visibility' (used by ;; `org-reveal') relies on overlays that aren't immediately available ;; when `org-mode' first initializes. (run-at-time 0.1 nil #'org-reveal '(4)))) ;;;###autoload (defun +org-remove-occur-highlights-h () "Remove org occur highlights on ESC in normal mode." (when org-occur-highlights (org-remove-occur-highlights) t)) ;;;###autoload (defun +org-enable-auto-update-cookies-h () "Update statistics cookies when saving or exiting insert mode (`evil-mode')." (when (bound-and-true-p evil-local-mode) (add-hook 'evil-insert-state-exit-hook #'org-update-parent-todo-statistics nil t)) (add-hook 'before-save-hook #'org-update-parent-todo-statistics nil t)) (general-def 'normal org-mode-map "C-" '+org/insert-item-below) (general-def 'insert org-mode-map "C-" '+org/insert-item-below) (use-package org-re-reveal :ensure nil :config (setq org-re-reveal-root "file:///home/chris/org/presentations/reveal.js/" org-re-reveal-theme "serif" org-re-reveal-transition "slide" org-re-reveal-mobile-app t) ) (use-package ox-zola :after 'ox-hugo :config ) (use-package unicode-fonts :ensure t :config (unicode-fonts-setup)) (use-package emojify :ensure t :hook (after-init . global-emojify-mode) :config (setq emojify-display-style 'image) :general (chris/leader-keys :states 'normal :keymaps 'override "ie" '(emojify-insert-emoji :which-key "insert emoji"))) (global-auto-revert-mode 1) (setq global-auto-revert-non-file-buffers t) (use-package visual-fill-column :after org :config (setq visual-fill-column-width 100 visual-fill-column-center-text t)) (use-package toc-org :after org) (use-package pulsar :config (setq pulsar-pulse-functions ;; NOTE 2022-04-09: The commented out functions are from before ;; the introduction of `pulsar-pulse-on-window-change'. Try that ;; instead. '(recenter-top-bottom move-to-window-line-top-bottom reposition-window ;; bookmark-jump ;; other-window ;; delete-window ;; delete-other-windows forward-page backward-page scroll-up-command scroll-down-command ;; windmove-right ;; windmove-left ;; windmove-up ;; windmove-down ;; windmove-swap-states-right ;; windmove-swap-states-left ;; windmove-swap-states-up ;; windmove-swap-states-down ;; tab-new ;; tab-close ;; tab-next org-next-visible-heading org-previous-visible-heading org-forward-heading-same-level org-backward-heading-same-level outline-backward-same-level outline-forward-same-level outline-next-visible-heading outline-previous-visible-heading outline-up-heading)) (setq pulsar-pulse-on-window-change t) (setq pulsar-pulse t) (setq pulsar-delay 0.055) (setq pulsar-iterations 10) (setq pulsar-face 'ffap) (setq pulsar-highlight-face 'pulsar-yellow) (pulsar-global-mode 1) ;; integration with the `consult' package: (add-hook 'consult-after-jump-hook #'pulsar-recenter-top) (add-hook 'consult-after-jump-hook #'pulsar-reveal-entry) ;; integration with the built-in `imenu': (add-hook 'imenu-after-jump-hook #'pulsar-recenter-top) (add-hook 'imenu-after-jump-hook #'pulsar-reveal-entry)) (setq home-directory "~/") (defun chris/eww-mpv () "Launch the url in mpv" (interactive) (let ((pt (avy-with ace-link-eww (avy-process (mapcar #'cdr (ace-link--eww-collect)) (avy--style-fn avy-style))))) (when (number-or-marker-p pt) (goto-char pt) (let ((url (get-text-property (point) 'shr-url))) (if (start-process "mpv" "mpv-output" "mpv" url) (message (concat "mpv started => " url)) (message "mpv failed, maybe this isn't a link?")))))) ;; (defun chris/) (defun chris/eww-video-dl () "Download the video at the url" (interactive) (let ((pt (avy-with ace-link-eww (avy-process (mapcar #'cdr (ace-link--eww-collect)) (avy--style-fn avy-style))))) (when (number-or-marker-p pt) (goto-char pt) (let ((url (get-text-property (point) 'shr-url))) (if (start-process "yt-dlp" "yt-dlp-output" "yt-dlp" "-o" (concat home-directory "Videos/%(title)s.%(ext)s") url) (message (concat "downloading => " url)) (message "idk this failed I guess...")) (pop-to-buffer "yt-dlp-output") (comint-mode) (evil-normal-state) (general-def 'normal comint-mode-map "q" 'kill-buffer-and-window))))) (setq eww-search-prefix "https://search.tfcconnection.org/search?q=") (general-def 'normal eww-mode-map "gv" 'chris/eww-mpv "gV" 'chris/eww-video-dl) (use-package vertico :init (vertico-mode) ;; Different scroll margin ;; (setq vertico-scroll-margin 0) ;; Show more candidates (setq vertico-count 10) ;; Grow and shrink the Vertico minibuffer (setq vertico-resize t) ;; Optionally enable cycling for `vertico-next' and `vertico-previous'. (setq vertico-cycle t) :general (general-def 'vertico-map "C-j" 'vertico-next "C-k" 'vertico-previous) ) ;; Persist history over Emacs restarts. Vertico sorts by history position. (use-package savehist :init (savehist-mode)) ;; A few more useful configurations... (use-package emacs :init ;; Add prompt indicator to `completing-read-multiple'. ;; Alternatively try `consult-completing-read-multiple'. (defun crm-indicator (args) (cons (concat "[CRM] " (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator) ;; Do not allow the cursor in the minibuffer prompt (setq minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) ;; Emacs 28: Hide commands in M-x which do not work in the current mode. ;; Vertico commands are hidden in normal buffers. ;; (setq read-extended-command-predicate ;; #'command-completion-default-include-p) ;; Enable recursive minibuffers (setq enable-recursive-minibuffers t)) (use-package consult :after vertico :config (setq consult-narrow-key "C-n" consult-project-root-function 'projectile-project-root) (consult-customize consult-org-heading :preview-key nil) (defun chris/consult-ripgrep-for-stepdata () "Make ripgrep search hidden files for stepdata" (interactive) (let ((consult-ripgrep-args (concat "rg " "--null " "--line-buffered " "--color=never " "--max-columns=1000 " "--path-separator / " "--no-heading " "--line-number " ;; adding these to default "--smart-case " "--hidden " ;; defaults "." ))) (consult-ripgrep))) :general (chris/leader-keys :states 'normal :keymaps 'override "si" 'consult-imenu "so" 'consult-org-heading "sf" 'consult-find "sm" 'bookmark-jump "sf" 'consult-flymake "sy" 'consult-yank-from-kill-ring "sb" 'consult-eglot-symbols)) (use-package marginalia :bind (:map minibuffer-local-map ("C-M-a" . marginalia-cycle) ;; :map embark-general-map ;; ("A" . marginalia-cycle) ) ;; The :init configuration is always executed (Not lazy!) :init ;; Must be in the :init section of use-package such that the mode gets ;; enabled right away. Note that this forces loading the package. (marginalia-mode) ;; When using Selectrum, ensure that Selectrum is refreshed when cycling annotations. ;; (advice-add #'marginalia-cycle :after ;; (lambda () (when (bound-and-true-p selectrum-mode) (selectrum-exhibit)))) ;; Prefer richer, more heavy, annotations over the lighter default variant. (setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) :after vertico :config (setq marginalia--cache-size 60000)) (use-package all-the-icons-completion :after vertico :config (all-the-icons-completion-mode)) (use-package embark :ensure t :general ('vertico-map "C-'" 'embark-act) ('normal 'org-mode-map "C-'" 'embark-act) :config (defun embark-which-key-indicator () "An embark indicator that displays keymaps using which-key. The which-key help message will show the type and value of the current target followed by an ellipsis if there are further targets." (lambda (&optional keymap targets prefix) (if (null keymap) (which-key--hide-popup-ignore-command) (which-key--show-keymap (if (eq (plist-get (car targets) :type) 'embark-become) "Become" (format "Act on %s '%s'%s" (plist-get (car targets) :type) (embark--truncate-target (plist-get (car targets) :target)) (if (cdr targets) "…" ""))) (if prefix (pcase (lookup-key keymap prefix 'accept-default) ((and (pred keymapp) km) km) (_ (key-binding prefix 'accept-default))) keymap) nil nil t (lambda (binding) (not (string-suffix-p "-argument" (cdr binding)))))))) (setq embark-indicators '(embark-which-key-indicator embark-highlight-indicator embark-isearch-highlight-indicator)) (defun embark-hide-which-key-indicator (fn &rest args) "Hide the which-key indicator immediately when using the completing-read prompter." (which-key--hide-popup-ignore-command) (let ((embark-indicators (remq #'embark-which-key-indicator embark-indicators))) (apply fn args))) (advice-add #'embark-completing-read-prompter :around #'embark-hide-which-key-indicator) ) (use-package embark-consult) (use-package wgrep) (use-package corfu :ensure t ;; Optional customizations :custom (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' (corfu-auto t) ;; Enable auto completion (corfu-separator ?\s) ;; Orderless field separator (corfu-quit-no-match 'separator) ;; Never quit, even if there is no match (corfu-preview-current 'insert) ;; Enable current candidate preview (corfu-preselect-first nil) ;; Enable candidate preselection (corfu-on-exact-match 'insert) ;; Configure handling of exact matches (corfu-echo-documentation '(1.0 . 0.2)) ;; Disable documentation in the echo area (corfu-scroll-margin 5) ;; Use scroll margin (corfu-count 15) (corfu-auto-prefix 2) (corfu-auto-delay 0.5) ;; You may want to enable Corfu only for certain modes. ;; :hook ((prog-mode . corfu-mode) ;; (shell-mode . corfu-mode) ;; (eshell-mode . corfu-mode)) ;; Recommended: Enable Corfu globally. ;; This is recommended since dabbrev can be used globally (M-/). :init (global-corfu-mode) :general ('corfu-map "C-j" 'corfu-next "C-k" 'corfu-previous "M-SPC" 'corfu-insert-separator)) ;; Optionally use the `orderless' completion style. See `+orderless-dispatch' ;; in the Consult wiki for an advanced Orderless style dispatcher. ;; Enable `partial-completion' for files to allow path expansion. ;; You may prefer to use `initials' instead of `partial-completion'. (use-package orderless :ensure t :init ;; Configure a custom style dispatcher (see the Consult wiki) ;; (setq orderless-style-dispatchers '(+orderless-dispatch) ;; orderless-component-separator #'orderless-escapable-split-on-space) (setq completion-styles '(orderless) completion-category-defaults nil completion-category-overrides '((file (styles . (partial-completion))))) (defun flex-if-twiddle (pattern _index _total) (when (string-prefix-p "~" pattern) `(orderless-flex . ,(substring pattern 1)))) (defun first-initialism (pattern index _total) (if (= index 0) 'orderless-initialism)) (defun without-if-bang (pattern _index _total) (cond ((equal "!" pattern) '(orderless-literal . "")) ((string-prefix-p "!" pattern) `(orderless-without-literal . ,(substring pattern 1))))) (setq orderless-matching-styles '(orderless-literal orderless-regexp) orderless-style-dispatchers '(flex-if-twiddle without-if-bang)) ) ;; Use dabbrev with Corfu! (use-package dabbrev :after corfu ;; Swap M-/ and C-M-/ :bind (("M-/" . dabbrev-completion) ("C-M-/" . dabbrev-expand))) (use-package cape :ensure t ;; Bind dedicated completion commands :bind (("C-c p p" . completion-at-point) ;; capf ("C-c p t" . complete-tag) ;; etags ("C-c p d" . cape-dabbrev) ;; or dabbrev-completion ("C-c p f" . cape-file) ("C-c p k" . cape-keyword) ("C-c p s" . cape-symbol) ("C-c p a" . cape-abbrev) ("C-c p i" . cape-ispell) ("C-c p l" . cape-line) ("C-c p w" . cape-dict) ("C-c p \\" . cape-tex) ("C-c p _" . cape-tex) ("C-c p ^" . cape-tex) ("C-c p &" . cape-sgml) ("C-c p r" . cape-rfc1345)) :init ;; Add `completion-at-point-functions', used by `completion-at-point'. (add-to-list 'completion-at-point-functions #'cape-file) ;; (add-to-list 'completion-at-point-functions #'cape-tex) (add-to-list 'completion-at-point-functions #'cape-keyword) (add-to-list 'completion-at-point-functions #'cape-dabbrev) ;;(add-to-list 'completion-at-point-functions #'cape-sgml) ;;(add-to-list 'completion-at-point-functions #'cape-rfc1345) ;;(add-to-list 'completion-at-point-functions #'cape-abbrev) (add-to-list 'completion-at-point-functions #'cape-ispell) ;;(add-to-list 'completion-at-point-functions #'cape-dict) ;; (add-to-list 'completion-at-point-functions #'cape-symbol) ;;(add-to-list 'completion-at-point-functions #'cape-line) :config (setq cape-dabbrev-min-length 4) ) (use-package kind-icon :ensure t :after corfu :custom (kind-icon-default-face 'corfu-default) ; to compute blended backgrounds correctly :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)) (use-package devdocs :config (evil-collection-devdocs-setup) :general (chris/leader-keys 'normal "hd" 'devdocs-lookup)) (use-package tempel :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand ("M-'" . tempel-insert) ("C-M-" . tempel-done)) :init ;; Setup completion at point (defun tempel-setup-capf () ;; Add the Tempel Capf to `completion-at-point-functions'. `tempel-expand' ;; only triggers on exact matches. Alternatively use `tempel-complete' if ;; you want to see all matches, but then Tempel will probably trigger too ;; often when you don't expect it. ;; NOTE: We add `tempel-expand' *before* the main programming mode Capf, ;; such that it will be tried first. (setq-local completion-at-point-functions (cons #'tempel-complete completion-at-point-functions))) (add-hook 'prog-mode-hook 'tempel-setup-capf) (add-hook 'text-mode-hook 'tempel-setup-capf) ;; Optionally make the Tempel templates available to Abbrev, ;; either locally or globally. `expand-abbrev' is bound to C-x '. ;; (add-hook 'prog-mode-hook #'tempel-abbrev-mode) ;; (tempel-global-abbrev-mode) :general (chris/leader-keys "ic" 'tempel-insert) ) (use-package projectile :ensure t :general (chris/leader-keys :states 'normal :keymaps 'override "op" 'projectile-switch-open-project "gc" 'projectile-compile-project "gr" 'projectile-run-project "gd" 'projectile-run-gdb "fp" 'project-find-file "fP" 'project-switch-project)) (use-package simple-httpd :ensure t) (use-package avy :after evil) (use-package evil-avy :after avy :general (general-define-key :states 'normal :keymaps '(override magit-mode-map) "F" 'magit-pull) (general-def 'normal "gl" 'avy-goto-line)) (use-package ace-link :after avy :general (general-def 'normal "gL" 'ace-link)) (setq display-buffer-alist (if (string= system-name "syl") '(("\\*e?shell\\*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("\\*e?shell-terminal\\*" (display-buffer-same-window)) ("*helpful*" (display-buffer-in-side-window) (side . right) (window-width . 0.4)) ("*compilation*" (display-buffer-in-side-window) (side . right) (window-width . 0.4)) ("*rustic-compilation*" (display-buffer-in-side-window) (side . right) (window-width . 0.4)) ("*gud-presenter*" (display-buffer-in-side-window) (side . right) (window-width . 0.4)) ("*dired-side*" (display-buffer-in-side-window) (side . left) (window-width . 0.3)) ("*org-roam*" (display-buffer-in-side-window) (side . right) (window-width . 0.4)) ("\\*elfeed-entry\\*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.60)) ("*Agenda Commands*" (display-buffer-in-side-window) (side . right) (window-width . 0.30)) ("\\*Bongo-Elfeed Queue\\*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("\\*Async Shell Command\\*" (display-buffer-no-window)) ) '(("\\*e?shell\\*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("\\*e?shell-terminal\\*" (display-buffer-same-window)) ("*helpful*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("*compilation*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("*rustic-compilation*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("*gud-presenter*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("*org-roam*" (display-buffer-in-side-window) (side . right) (window-width . 0.3)) ("\\*elfeed-entry\\*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.70)) ("*Agenda Commands*" (display-buffer-in-side-window) (side . right) (window-width . 0.30)) ("\\*Bongo-Elfeed Queue\\*" (display-buffer-in-side-window) (side . bottom) (window-height . 0.25)) ("\\*Async Shell Command\\*" (display-buffer-no-window)) ) )) (defun chris/kill-buffer-frame () "Kills the active buffer and frame" (interactive) (kill-this-buffer) (delete-frame)) (use-package ace-window :config (ace-window-display-mode) :general (chris/leader-keys :states 'normal :keymaps 'override "ww" '(ace-window :which-key "select window"))) (use-package helpful :ensure nil :commands (helpful-callable helpful-variable helpful-command helpful-key) :general (general-def 'normal 'helpful-mode-map "q" 'helpful-kill-buffers) :config (defun helpful--autoloaded-p (sym buf) "Return non-nil if function SYM is autoloaded." (-when-let (file-name (buffer-file-name buf)) (setq file-name (s-chop-suffix ".gz" file-name)) (condition-case nil (help-fns--autoloaded-p sym file-name) ; new in Emacs 29.0.50 ; see https://github.com/Wilfred/helpful/pull/283 (error (help-fns--autoloaded-p sym))))) (defun helpful--skip-advice (docstring) "Remove mentions of advice from DOCSTRING." (let* ((lines (s-lines docstring)) (relevant-lines (--take-while (not (or (s-starts-with-p ":around advice:" it) (s-starts-with-p "This function has :around advice:" it))) lines))) (s-trim (s-join "\n" relevant-lines))))) (use-package format-all :config (format-all-mode +1) (setq format-all-formatters '("Emacs Lisp" emacs-lisp)) :defer 1) (defvar read-symbol-positions-list nil) (add-to-list 'comint-output-filter-functions 'ansi-color-process-output) (add-hook 'comint-mode-hook 'ansi-color-for-comint-mode-on) (add-hook 'compilation-filter-hook 'ansi-color-for-comint-mode-on) (add-hook 'comint-mode-hook 'hl-line-mode) (add-hook 'prog-mode-hook 'hl-line-mode) (add-hook 'prog-mode-hook 'hs-minor-mode) (add-to-list 'auto-mode-alist '("\\.yuck?\\'" . lisp-data-mode)) (defun astyle-this-buffer () "Use astyle command to auto format c/c++ code." (interactive "r") (let* ((original-point (point))) ;; save original point before processing, thanks to @Scony (progn (if (executable-find "astyle") (shell-command-on-region (point-min) (point-max) (concat "astyle" " --style=" cc-mode-code-style " --indent=spaces=" (number-to-string c-basic-offset) " --pad-oper" " --pad-header" " --break-blocks" " --delete-empty-lines" " --align-pointer=type" " --align-reference=name") (current-buffer) t (get-buffer-create "*Astyle Errors*") t) (message "Cannot find binary \"astyle\", please install first.")) (goto-char original-point)))) ;; restore original point (defun astyle-before-save () "Auto styling before saving." (interactive) (when (member major-mode '(cc-mode c++-mode c-mode)) (astyle-this-buffer))) (add-hook 'c-mode-common-hook (lambda () (add-hook 'before-save-hook 'astyle-before-save))) (use-package rustic :config ;; comment to disable rustfmt on save (setq rustic-format-on-save t rustic-lsp-client 'eglot) :general (general-def 'normal rustic-mode-map "!" 'rustic-run-shell-command "gC" 'rustic-cargo-check "gA" 'rustic-cargo-add) (chris/leader-keys :states 'normal :keymaps 'override "gc" 'rustic-compile)) (use-package web-mode :mode "\\.html\\'" :config (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.phtml?\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.djhtml?\\'" . web-mode)) (setq web-mode-enable-auto-pairing t web-mode-enable-auto-expanding t web-mode-enable-auto-closing t web-mode-enable-current-column-highlight t web-mode-enable-current-element-highlight t) :general (general-def 'normal web-mode-map "TAB" 'indent-according-to-mode) (general-def 'insert web-mode-map "TAB" 'indent-according-to-mode) ) (use-package lua-mode :mode ("\\.lua\\'" . lua-mode)) (use-package nix-mode :mode "\\.nix\\'") (use-package eglot :commands eglot :hook (c++-mode . eglot-ensure) (c++-ts-mode . eglot-ensure) (rust-mode . eglot-ensure) (rustic-mode . eglot-ensure) (rust-ts-mode . eglot-ensure) :general (general-def 'normal eglot-mode-map "ga" 'eglot-code-actions)) (use-package consult-eglot :general (general-def 'normal eglot-mode-map "gs" 'consult-eglot-symbols)) (use-package cmake-mode :mode ("\\CMakeLists.txt\\'" . cmake-mode)) (use-package fennel-mode :mode ("\\.fnl\\'" . fennel-mode)) (use-package yaml-mode :mode ("\\.yml\\'" . yaml-mode)) (use-package docker :defer t :config (setq docker-run-as-root t)) (use-package docker-tramp :after docker) (use-package fish-mode :mode ("\\.fish\\'" . fish-mode)) (use-package markdown-mode :mode (("\\.md\\'" . markdown-mode) ("\\.rmd\\'". markdown-mode)) :config (setq markdown-fontify-code-blocks-natively t) (add-hook 'markdown-mode-hook 'chris/org-mode-setup) :general (general-def 'normal markdown-mode-map "C-j" 'markdown-next-visible-heading "M-j" 'markdown-move-down "C-k" 'markdown-previous-visible-heading "M-k" 'markdown-move-up)) (use-package qml-mode :mode ("\\.qml\\'" . qml-mode)) ;; (use-package company-qml ;; :after qml-mode ;; :config ;; ;; (add-to-list 'company-backends 'company-qml) ;; ) ;; (setq company-backends ;; '(company-bbdb company-semantic company-cmake company-capf company-clang company-files ;; (company-dabbrev-code company-gtags company-etags company-keywords) ;; company-oddmuse company-dabbrev)) ;; (use-package qt-pro-mode ;; :after qml-mode) (use-package csv-mode :mode ("\\.csv\\'" . csv-mode)) (use-package restclient :commands (restclient-mode)) (use-package ob-restclient :after org) (use-package dart-mode :mode ("\\.dart\\'" . dart-mode) :hook (dart-mode . lsp-deferred) :general (general-def 'normal dart-mode-map "gr" 'flutter-run-or-hot-reload "gR" 'lsp-dart-dap-flutter-hot-restart)) (use-package flutter :after dart :general (chris/leader-keys dart-mode-map "rf" 'flutter-run-or-hot-reload)) (use-package hover :after dart) (add-to-list 'exec-path "/opt/android-sdk/cmdline-tools/latest/bin") (use-package direnv :config (direnv-mode)) (use-package dired :ensure nil :config (defun chris/dired-open-xdg () "Open the file-at-point in the appropriate program" (interactive) (let ((file (file-truename (ignore-errors (dired-get-file-for-visit))))) (message file) (call-process "xdg-open" nil 0 nil file))) (defun chris/dired-open-wm () "Open dired as file-manager in wm" (interactive) (with-selected-frame (make-frame '((name . "dired"))) (dired-jump) (toggle-truncate-lines +1))) (defun chris/dired-open-videos () "Open dired in Videos as file-manager in wm" (interactive) (with-selected-frame (make-frame '((name . "dired"))) (dired "~/Videos/") (toggle-truncate-lines +1))) (defun chris/setup-dired () "setup dired" (setq truncate-lines t) (visual-line-mode nil) (dired-hide-details-mode t)) (defun chris/open-dired-sidewindow () "Open dired as a side window to the main window on the left" (interactive) (with-current-buffer (get-buffer-create "dired-side") (dired-jump))) (setq dired-dwim-target t delete-by-moving-to-trash t dired-mouse-drag-files t) (setq dired-listing-switches "-aoh --group-directories-first") (setq dired-hide-details-hide-symlink-targets nil dired-kill-when-opening-new-dired-buffer t) (add-hook 'dired-mode-hook 'chris/setup-dired) :general (chris/leader-keys :states 'normal :keymaps 'override "od" '(dired-jump :which-key "open dired here") "oD" '(dired :which-key "open dired select")) ('normal dired-mode-map "q" 'kill-this-buffer "C-" 'chris/dired-open-xdg "M-" 'ffap-other-window "C-'" 'embark-act)) (defun chris/dired-yank-filename () "Get the full filename from file at point and put into kill-ring" (interactive) (let* ((file (dired-get-filename))) (clipboard-kill-ring-save nil nil file))) (use-package dired-sidebar :ensure t :commands (dired-sidebar-toggle-sidebar) :general (general-def 'normal "gD" 'dired-sidebar-toggle-sidebar)) (use-package all-the-icons-dired :hook (dired-mode . all-the-icons-dired-mode)) (use-package dired-single :after dired :general (general-def 'normal dired-mode-map "h" 'dired-single-up-directory "l" 'dired-single-buffer)) (use-package fd-dired) (use-package dired-rainbow :after dired :config (defconst chris/dired-media-files-extensions '("mp3" "mp4" "MP3" "MP4" "avi" "mpg" "flv" "ogg" "opus") "Media files.") (defconst chris/dired-image-files-extensions '("png" "jpg" "PNG" "JPG" "jpeg" "JPEG" "gif" "GIF") "image files") (dired-rainbow-define html "#4e9a06" ("htm" "html" "xhtml")) (dired-rainbow-define media "#f3f99d" chris/dired-media-files-extensions) (dired-rainbow-define image "#5af78e" chris/dired-image-files-extensions) (dired-rainbow-define log (:inherit default :italic t) ".*\\.log")) (use-package diredfl :after dired :config (diredfl-global-mode +1)) (use-package dired-rsync :general (general-def 'normal dired-mode-map "C" 'dired-rsync)) (require 'tramp) (add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:")) (add-to-list 'tramp-default-proxies-alist '((regexp-quote (system-name)) nil nil)) (use-package ledger-mode) (use-package mu4e :load-path "/usr/share/emacs/site-lisp/mu4e/" :init (setq mu4e-maildir "~/Maildir" user-full-name "Chris Cochrun" mu4e-change-filenames-when-moving t mu4e-get-mail-command "mbsync -a" mu4e-update-interval (* 15 60) mu4e-attachment-dir "/home/chris/nextcloud/home/Documents/attachments" mu4e-completing-read-function #'completing-read mu4e-mu-binary "/etc/profiles/per-user/chris/bin/mu" mu4e-compose-signature-auto-include nil mu4e-headers-fields '((:human-date . 12) (:flags . 10) (:from . 22) (:subject)) mu4e-headers-flagged-mark '("F" . " ") mu4e-headers-replied-mark '("R" . " ") mu4e-headers-personal-mark '("p" . " ") mu4e-headers-list-mark '("s" . " ")) :config (setq mail-user-agent 'mu4e-user-agent) (setq mu4e-contexts (list (make-mu4e-context :name "work" :match-func (lambda (msg) (when msg (string-prefix-p "/office" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "chris@tfcconnection.org") (mu4e-sent-folder . "/office/Sent Items/") (mu4e-drafts-folder . "/office/Drafts") (mu4e-trash-folder . "/office/Deleted Items") (mu4e-refile-folder . "/office/Archive") (smtpmail-smtp-user . "chris@tfcconnection.org") (smtpmail-starttls-credentials . '(("smtp.office365.com" 587 nil nil))) (smtpmail-auth-credentials . '(("smtp.office365.com" 587 "chris@tfcconnection.org" nil))) (smtpmail-smtp-server . "smtp.office365.com") (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun"))) (make-mu4e-context :name "outlook" :match-func (lambda (msg) (when msg (string-prefix-p "/outlook" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "chris.cochrun@outlook.com") (mu4e-sent-folder . "/outlook/Sent/") (mu4e-drafts-folder . "/outlook/Drafts") (mu4e-trash-folder . "/outlook/Deleted") (mu4e-refile-folder . "/outlook/Archive") (smtpmail-smtp-user . "chris.cochrun@outlook.com") (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun"))) (make-mu4e-context :name "personal" :match-func (lambda (msg) (when msg (string-prefix-p "/cochrun" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "chris@cochrun.xyz") (mu4e-sent-folder . "/cochrun/Sent/") (mu4e-drafts-folder . "/cochrun/Drafts") (mu4e-trash-folder . "/cochrun/Trash") (mu4e-refile-folder . "/cochrun/Archive") (smtpmail-smtp-user . "chris@cochrun.xyz") (smtpmail-starttls-credentials . '(("mail.cochrun.xyz" 587 nil nil))) (smtpmail-auth-credentials . '(("mail.cochrun.xyz" 587 "chris@cochrun.xyz" nil))) (smtpmail-smtp-server . "mail.cochrun.xyz") (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun\nchris@tfcconnection.org\nchris@cochrun.xyz"))) (make-mu4e-context :name "gmail" :match-func (lambda (msg) (when msg (string-prefix-p "/gmail" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "ccochrun21@gmail.com") (mu4e-sent-folder . "/gmail/[Gmail].Sent Mail/") (smtpmail-smtp-user . "ccochrun21@gmail.com") (mu4e-compose-signature . "Praising God in all things,\nChris Cochrun"))))) ;; Add the ability to send email (setq message-send-mail-function 'smtpmail-send-it starttls-use-gnutls t smtpmail-default-smtp-server "mail.cochrun.xyz" smtpmail-smtp-service 587) ;; shortcuts in the jumplist by pressing "J" in the mu4e buffer (setq mu4e-maildir-shortcuts '((:maildir "/office/Archive" :key ?a) (:maildir "/office/INBOX" :key ?i) (:maildir "/cochrun/INBOX" :key ?p) (:maildir "/outlook/INBOX" :key ?l) (:maildir "/office/Junk Email" :key ?j) (:maildir "/office/INBOX/Website Forms" :key ?f) (:maildir "/gmail/INBOX" :key ?g) (:maildir "/office/Sent Items" :key ?s))) ;; (add-to-list mu4e-headers-actions ("org capture message" . mu4e-org-store-and-capture)) (setq mu4e-bookmarks '((:name "Unread messages" :query "flag:unread AND NOT flag:trashed AND NOT maildir:\"/outlook/Junk\" AND NOT maildir:\"/office/Junk Email\" AND NOT maildir:\"/outlook/Deleted\" AND NOT maildir:\"/office/Deleted Items\" AND NOT maildir:\"/office/Archive\" AND NOT maildir:\"/outlook/Archive\" AND NOT maildir:\"/cochrun/Archive\" AND NOT maildir:\"/cochrun/Junk\"" :key 117) (:name "Today's messages" :query "date:today..now" :key 116) (:name "Last 7 days" :query "date:7d..now" :hide-unread t :key 119) (:name "Messages with images" :query "mime:image/*" :key 112))) (setq mu4e-view-prefer-html nil shr-color-visible-luminance-min 80) (setq mu4e-use-fancy-chars t mu4e-headers-draft-mark '("D" . "") mu4e-headers-flagged-mark '("F" . "") mu4e-headers-new-mark '("N" . " ") mu4e-headers-passed-mark '("P" . "") mu4e-headers-replied-mark '("R" . "") mu4e-headers-seen-mark '("S" . " ") mu4e-headers-trashed-mark '("T" . " ") mu4e-headers-attach-mark '("a" . " ") mu4e-headers-encrypted-mark '("x" . "") mu4e-headers-signed-mark '("s" . " ") mu4e-headers-unread-mark '("u" . " ")) (setq mu4e-headers-fields '((:human-date . 12) (:flags . 6) (:from . 22) (:subject))) (setq mu4e-view-actions '(("capture message" . mu4e-action-capture-message) ("view in browser" . mu4e-action-view-in-browser) ("show this thread" . mu4e-action-show-thread))) (defun chris/setup-mu4e-headers () (toggle-truncate-lines +1) (display-line-numbers-mode -1)) (defun chris/setup-mu4e-view () (display-line-numbers-mode -1) (toggle-truncate-lines +1) (setq visual-fill-column-center-text t) (setq visual-fill-column-width 100) (visual-fill-column-mode +1)) (remove-hook 'mu4e-main-mode-hook '(display-line-numbers-mode -1)) (add-hook 'mu4e-headers-mode-hook #'chris/setup-mu4e-headers) (add-hook 'mu4e-view-mode-hook #'chris/setup-mu4e-view) (mu4e t) :general (chris/leader-keys :states 'normal :keymaps 'override "om" 'mu4e) (general-def 'normal mu4e-view-mode-map "ga" 'mu4e-view-save-attachments)) (use-package org-msg :hook (mu4e-compose-mode . org-msg-edit-mode) :config (org-msg-mode) (setq mail-user-agent 'mu4e-user-agent org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t" org-msg-startup "hidestars indent inlineimages" org-msg-greeting-fmt "\n%s\n" org-msg-recipient-names '(("chris@tfcconnection.org" . "Chris Cochrun")) org-msg-greeting-name-limit 3 org-msg-default-alternatives '((new . (text html)) (reply-to-html . (text html)) (reply-to-text . (text))) org-msg-convert-citation t org-msg-signature " #+begin_signature -- *Chris* /Praising God in all things!/ #+end_signature")) (use-package calfw :commands chris/calfw-calendar-open :config (defun chris/calfw-calendar-open () (interactive) (cfw:open-calendar-buffer :contents-sources (list (cfw:org-create-source "Cyan") ; org-agenda source (cfw:ical-create-source "NV" "https://thrillshare-cmsv2.services.thrillshare.com/api/v4/o/6958/cms/events/generate_ical?filter_ids§ion_ids" "Green") ; School Calendar (cfw:ical-create-source "Outlook" "https://outlook.office365.com/owa/calendar/62a0d491bec4430e825822afd2fd1c01@tfcconnection.org/9acc5bc27ca24ce7a900c57284959f9d8242340735661296952/S-1-8-2197686000-2519837503-3687200543-3873966527/reachcalendar.ics" "Yellow") ; Outlook Calendar ))) (custom-set-faces '(cfw:face-title ((t (:weight bold :height 2.0 :inherit fixed-pitch)))) '(cfw:face-header ((t (:slant italic :weight bold)))) '(cfw:face-sunday ((t :weight bold))) '(cfw:face-saturday ((t :weight bold))) '(cfw:face-holiday ((t :weight bold))) ;; '(cfw:face-grid ((t :foreground "DarkGrey"))) '(cfw:face-default-content ((t :height 0.7))) ;; '(cfw:face-periods ((t :foreground "cyan"))) '(cfw:face-day-title ((t (:background nil)))) '(cfw:face-default-day ((t :weight bold :inherit cfw:face-day-title))) '(cfw:face-annotation ((t :inherit cfw:face-day-title))) '(cfw:face-disable ((t :inherit cfw:face-day-title))) '(cfw:face-today-title ((t :weight bold))) '(cfw:face-today ((t :weight bold))) ;; '(cfw:face-select ((t :background "#2f2f2f"))) '(cfw:face-toolbar ((t :foreground "Steelblue4" :background "Steelblue4"))) '(cfw:face-toolbar-button-off ((t :weight bold))) '(cfw:face-toolbar-button-on ((t :weight bold)))) (setq cfw:fchar-junction ?╋ cfw:fchar-vertical-line ?┃ cfw:fchar-horizontal-line ?━ cfw:fchar-left-junction ?┣ cfw:fchar-right-junction ?┫ cfw:fchar-top-junction ?┯ cfw:fchar-top-left-corner ?┏ cfw:fchar-top-right-corner ?┓) :general (chris/leader-keys :states 'normal :keymaps 'override "oc" 'chris/calfw-calendar-open) (general-def cfw:calendar-mode-map "q" 'kill-this-buffer "RET" 'cfw:show-details-command) (general-def 'normal cfw:details-mode-map "q" 'cfw:details-kill-buffer-command)) (use-package calfw-org :after calfw) (use-package calfw-ical :after calfw) (use-package org-caldav :after org :config (setq org-caldav-url "https://staff.tfcconnection.org/remote.php/dav/calendars/chris" org-caldav-calendar-id "org" org-caldav-inbox "/home/chris/org/todo/inbox.org" org-caldav-files '("/home/chris/org/todo/todo.org" "/home/chris/org/todo/notes.org" "/home/chris/org/todo/prayer.org") org-icalendar-alarm-time 15 org-icalendar-use-scheduled '(todo-start event-if-todo))) (use-package org-wild-notifier :after org :config (setq alert-default-style 'libnotify) (org-wild-notifier-mode +1)) (use-package magit :ensure nil :commands (magit-status magit-get-current-branch) :general (chris/leader-keys :states 'normal :keymaps 'override "g g" 'magit-status) :custom (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) (use-package eshell :ensure t :config (require 'em-tramp) (with-eval-after-load 'esh-module ;; REVIEW: It used to work, but now the early `provide' seems to backfire. (unless (boundp 'eshell-modules-list) (load "esh-module")) ;; Don't print the banner. (push 'eshell-tramp eshell-modules-list)) (setq password-cache t password-cache-expiry 3600) (setq eshell-history-size 1024) ;;; Extra execution information (defvar chris/eshell-status-p t "If non-nil, display status before prompt.") (defvar chris/eshell-status--last-command-time nil) (make-variable-buffer-local 'chris/eshell-status--last-command-time) (defvar chris/eshell-status-min-duration-before-display 0 "If a command takes more time than this, display its duration.") (defun chris/eshell-status-display () (if chris/eshell-status--last-command-time (let ((duration (time-subtract (current-time) chris/eshell-status--last-command-time))) (setq chris/eshell-status--last-command-time nil) (when (> (time-to-seconds duration) chris/eshell-status-min-duration-before-display) (format "  %.3fs %s" (time-to-seconds duration) (format-time-string "| %F %T" (current-time))))) (format "  0.000s"))) (defun chris/eshell-status-record () (setq chris/eshell-status--last-command-time (current-time))) (add-hook 'eshell-pre-command-hook 'chris/eshell-status-record) (setq eshell-prompt-function (lambda nil (let ((path (abbreviate-file-name (eshell/pwd)))) (concat (if (or (string= system-name "archdesktop") (string= system-name "syl")) nil (format (propertize "\n(%s@%s)" 'face '(:foreground "#606580")) (propertize (user-login-name) 'face '(:inherit compilation-warning)) (propertize (system-name) 'face '(:inherit compilation-warning)))) (if (and (require 'magit nil t) (or (magit-get-current-branch) (magit-get-current-tag))) (let* ((root (abbreviate-file-name (magit-rev-parse "--show-toplevel"))) (after-root (substring-no-properties path (min (length path) (1+ (length root)))))) (format (propertize "\n[ %s | %s@%s ]" 'face font-lock-comment-face) (propertize root 'face `(:inherit org-warning)) (propertize after-root 'face `(:inherit org-level-1 :height 1.0)) (propertize (or (magit-get-current-branch) (magit-get-current-tag)) 'face `(:inherit org-macro)))) (format (propertize "\n[%s]" 'face font-lock-comment-face) (propertize path 'face `(:inherit org-level-1)))) (when chris/eshell-status-p (propertize (or (chris/eshell-status-display) "") 'face font-lock-comment-face)) (propertize "\n" 'face '(:inherit org-todo :weight ultra-bold)) " ")))) ;;; If the prompt spans over multiple lines, the regexp should match ;;; last line only. (setq-default eshell-prompt-regexp "^ ") (setq eshell-destroy-buffer-when-process-dies t) (defun chris/pop-eshell () "Make an eshell frame on the bottom" (interactive) (unless pop-eshell (setq pop-eshell (eshell 100)) (with-current-buffer pop-eshell (eshell/clear-scrollback) (rename-buffer "*eshell-pop*") (display-buffer-in-side-window pop-eshell '((side . bottom)))))) (setq eshell-banner-message "") (setq eshell-path-env "/usr/local/bin:/usr/bin:/opt/android-sdk/cmdline-tools/latest/bin") ;; this makes it so flutter works properly (setenv "ANDROID_SDK_ROOT" "/opt/android-sdk") (setenv "CHROME_EXECUTABLE" "/usr/bin/qutebrowser") (setenv "JAVA_HOME" "/usr/lib/jvm/default") (add-hook 'eshell-mode-hook (lambda () (display-line-numbers-mode -1))) (setq eshell-command-aliases-list '(("q" "exit") ("f" "find-file $1") ("ff" "find-file $1") ("d" "dired $1") ("bd" "eshell-up $1") ("rg" "rg --color=always $*") ("ll" "ls -lah $*") ("less" "view-file $1") ("gg" "magit-status") ("clear" "clear-scrollback") ("!!" "eshell-previous-input 2") ("yay" "paru $1") ("yeet" "paru -Rns $1") ("nixs" "nix search nixpkgs $1") ("myip" "curl icanhazip.com") ("ytd" "yt-dlp -o ~/Videos/%(title)s.%(ext)s $1") ("nupg" "upgrade-nix") ("nupd" "update-nix") ("ksb" "/home/chris/dev/kde/src/kdesrc-build/kdesrc-build") ("ws" "rsync -avzP public/ chris@staff.tfcconnection.org:tfcconnection") ("wttr" "curl wttr.in/@home.cochrun.xyz"))) (defun chris/eshell-new() "Open a new eshell buffer" (interactive) (eshell 'N)) (defun chris/eshell-switch() "interactively switch between eshell buffers" (interactive) (consult-buffer)) (defun chris/eshell-window () "Open a new emacs window with eshell as a sole buffer" (interactive) (with-selected-frame (make-frame '((name . "*eshell-terminal*"))) (setq eshell-terminal (eshell 100)) (display-buffer-same-window (generate-new-buffer-name "*eshell-terminal*") '()) (eshell 100) (other-window 1) (switch-to-buffer "*eshell*<100>") (other-window 1) (delete-window))) (add-hook 'eshell-load-hook #'eat-eshell-mode) :general (chris/leader-keys :states 'normal :keymaps 'override "oe" 'chris/eshell-new "be" 'eshell) (general-def '(normal insert) eshell-mode-map "C-d" 'kill-buffer-and-window)) (add-hook 'eshell-load-hook #'eat-eshell-mode) (setq vterm-buffer-name-string "vterm %s") (defun chris/vterm-setup () "Setup vterm with my preferred settings" (display-line-numbers-mode -1)) (add-hook 'vterm-mode-hook 'chris/vterm-setup) (use-package sly :mode ("\\.lisp\\'" . sly-mode) ("\\.lisp\\'" . lisp-mode) :config (defun chris/start-nyxt-repl () "Start the repl and sly connection for nyxt" (interactive) (sly-connect "localhost" 4006))) (use-package pdf-tools :mode ("\\.pdf\\'" . pdf-view-mode) :init ;; (setq pdf-info-epdfinfo-program "/nix/store/6pc8vs42xbfah1h8h050a77p7vpr12kc-emacs-packages-deps/share/emacs/site-lisp/elpa/pdf-tools-20220823/epdfinfo" ;; pdf-tools-directory "/nix/store/6pc8vs42xbfah1h8h050a77p7vpr12kc-emacs-packages-deps/share/emacs/site-lisp/elpa/pdf-tools-20220823/") (pdf-tools-install) :config (custom-set-variables '(pdf-misc-print-program "/usr/bin/lpr") '(pdf-misc-print-program-args (quote ("-o media=Letter" "-o fitplot")))) (add-hook 'pdf-view-mode 'pdf-view-fit-page-to-window)) (use-package nov :mode ("\\.epub\\'" . nov-mode) :config (defun chris/setup-nov-mode (interactive) (visual-fill-column-mode) (display-line-numbers-mode -1) (variable-pitch-mode +1) (setq visual-fill-column-width 130 visual-fill-column-center-text t)) (add-hook 'nov-mode-hook 'chris/setup-nov-mode)) (use-package elfeed :commands (elfeed) :config (defvar chris/elfeed-bongo-playlist "*Bongo-Elfeed Queue*" "Name of the Elfeed+Bongo multimedia playlist.") (defun chris/elfeed-bongo-insert-item () "Insert `elfeed' multimedia links in `bongo' playlist buffer. The playlist buffer has a unique name so that it will never interfere with the default `bongo-playlist-buffer'." (interactive) (let* ((entry (elfeed-search-selected :ignore-region)) (link (elfeed-entry-link entry)) (enclosure (elt (car (elfeed-entry-enclosures entry)) 0)) (url (if (string-prefix-p "https://thumbnails" enclosure) link (if (string= enclosure nil) link enclosure))) (title (elfeed-entry-title entry)) (bongo-pl chris/elfeed-bongo-playlist) (buffer (get-buffer-create bongo-pl))) (message "link is %s" link) (message "enclosure is %s" enclosure) (message "url is %s" url) (message "title is %s" title) (elfeed-search-untag-all-unread) (unless (bongo-playlist-buffer) (bongo-playlist-buffer)) (display-buffer buffer) (with-current-buffer buffer (when (not (bongo-playlist-buffer-p)) (bongo-playlist-mode) (setq-local bongo-library-buffer (get-buffer "*elfeed-search*")) (setq-local bongo-enabled-backends '(mpv)) (bongo-progressive-playback-mode)) (goto-char (point-max)) (bongo-insert-uri url (format "%s ==> %s" title url)) (let ((inhibit-read-only t)) (delete-duplicate-lines (point-min) (point-max))) (bongo-recenter)) (message "Enqueued %s “%s” in %s" (if enclosure "podcast" "video") (propertize title 'face 'italic) (propertize bongo-pl 'face 'bold)))) (defun chris/elfeed-bongo-insert-link () "Inserts the hovered link into bongo for playback in mpv" (interactive) (let* ((link (shr--current-link-region)) (entry elfeed-show-entry) (title (elfeed-entry-title entry)) (url (get-text-property (point) 'shr-url)) (bongo-pl chris/elfeed-bongo-playlist) (buffer (get-buffer-create bongo-pl))) (message "url is %s" url) (message "title is %s" title) (unless (bongo-playlist-buffer) (bongo-playlist-buffer)) (display-buffer buffer) (with-current-buffer buffer (when (not (bongo-playlist-buffer-p)) (bongo-playlist-mode) (setq-local bongo-library-buffer (get-buffer "*elfeed-search*")) (setq-local bongo-enabled-backends '(mpv)) (bongo-progressive-playback-mode)) (goto-char (point-max)) (bongo-insert-uri url (format "%s ==> %s" title url)) (let ((inhibit-read-only t)) (delete-duplicate-lines (point-min) (point-max))) (bongo-recenter)) (message "Enqueued item “%s” in %s" (propertize title 'face 'italic) (propertize bongo-pl 'face 'bold)))) (defun chris/elfeed-bongo-switch-to-playlist () (interactive) (let* ((bongo-pl chris/elfeed-bongo-playlist) (buffer (get-buffer bongo-pl))) (if buffer (switch-to-buffer buffer) (message "No `bongo' playlist is associated with `elfeed'.")))) (setq elfeed-search-filter "@6-days-ago +unread") (defun chris/elfeed-ui-setup () (display-line-numbers-mode -1) (toggle-truncate-lines +1)) (defun chris/elfeed-show-ui-setup () (display-line-numbers-mode -1) (setq visual-fill-column-width 130 visual-fill-column-center-text t) (toggle-truncate-lines -1) (visual-fill-column-mode +1)) (add-hook 'elfeed-search-mode-hook 'chris/elfeed-ui-setup) (add-hook 'elfeed-show-mode-hook 'chris/elfeed-show-ui-setup) (setq shr-use-colors nil) (defun chris/elfeed-eww-browse () (interactive) (let* ((entry (elfeed-search-selected :ignore-region)) (link (elfeed-entry-link entry))) (message link) (eww link))) :general (chris/leader-keys :states 'normal :keymaps 'override "of" 'elfeed) (general-def 'normal elfeed-search-mode-map "v" 'chris/elfeed-bongo-insert-item "h" 'chris/elfeed-bongo-switch-to-playlist "b" 'chris/elfeed-eww-browse) (general-def 'normal elfeed-show-mode-map "b" 'eww)) (use-package elfeed-org :after elfeed :config (setq rmh-elfeed-org-files (list "~/org/elfeed.org")) (elfeed-org) (elfeed-update)) (use-package bongo :commands (bongo bongo-playlist-buffer) :config (setq bongo-default-directory "~/Music" bongo-prefer-library-buffers nil bongo-insert-whole-directory-trees t bongo-logo nil bongo-display-playback-mode-indicator t bongo-display-inline-playback-progress t bongo-field-separator (propertize " · " 'face 'shadow)) (define-bongo-backend mpv :constructor 'bongo-start-mpv-player :program-name 'mpv :extra-program-arguments '("--profile=fast --input-ipc-server=/tmp/mpvsocket") :matcher '((local-file "file:" "http:" "ftp:" "lbry:") "mpg" "mpeg" "vob" "avi" "ogm" "mp4" "mkv" "mov" "asf" "wmv" "rm" "rmvb" "ts") :matcher '(("mms:" "mmst:" "rtp:" "rtsp:" "udp:" "unsv:" "dvd:" "vcd:" "tv:" "dvb:" "mf:" "cdda:" "cddb:" "cue:" "sdp:" "mpst:" "tivo:") . t) :matcher '(("http:" "https:" "lbry:") . t)) (define-bongo-backend mpv-music :constructor 'bongo-start-mpv-player :program-name-variable 'mpv :extra-program-arguments '("--profile=slow --input-ipc-server=/tmp/mpvsocket") :matcher '((local-file "file:" "http:" "ftp:" "lbry:") "mka" "wav" "wma" "ogm" "opus" "ogg" "flac" "mp3" "mka" "wav") :matcher '(("http:" "https:" "lbry:") . t)) (setq bongo-custom-backend-matchers '((mpv-music local-file "mka" "wav" "wma" "ogm" "opus" "ogg" "flac" "mp3" "mka" "wav") (mpv local-file "mpg" "mpeg" "vob" "avi" "ogm" "mp4" "mkv" "mov" "asf" "wmv" "rm" "rmvb" "ts"))) (setq bongo-enabled-backends '(mpv mpv-music) bongo-track-mark-icon-file-name "track-mark-icon.png") (defun chris/bongo-mark-line-forward () (interactive) (bongo-mark-line) (goto-char (bongo-point-after-object)) (next-line)) (defun chris/bongo-mpv-pause/resume () (interactive) (bongo-mpv-player-pause/resume bongo-player)) (defun chris/bongo-mpv-speed-up () (interactive) (bongo--run-mpv-command bongo-player "speed" "set" "speed" "1.95")) (defun chris/bongo-open-elfeed-queue-buffer () (interactive) (display-buffer "*Bongo-Elfeed Queue*")) (defun chris/bongo-ytdlp () "Download the video or item using yt-dlp" (interactive) (while bongo-uri-p (message bongo-file-name))) :general (chris/leader-keys "ob" 'bongo "oB" 'chris/bongo-open-elfeed-queue-buffer "mi" 'bongo-insert-enqueue "mp" 'bongo-pause/resume) (general-def 'normal bongo-playlist-mode-map "RET" 'bongo-dwim "d" 'bongo-kill-line "u" 'bongo-unmark-region "p" 'bongo-pause/resume "P" 'bongo-yank "H" 'bongo-switch-buffers "q" 'bury-buffer "+" 'chris/bongo-mpv-speed-up "m" 'chris/bongo-mark-line-forward) (general-def 'normal bongo-library-mode-map "RET" 'bongo-dwim "d" 'bongo-kill-line "u" 'bongo-unmark-region "e" 'bongo-insert-enqueue "p" 'bongo-pause/resume "H" 'bongo-switch-buffers "q" 'bury-buffer)) (use-package emms :config (emms-all) (evil-collection-emms-setup) (setq emms-player-list '(emms-player-vlc)) (setq emms-source-file-default-directory "~/Music/" emms-tag-editor-tag-ogg-program "mid3v2") (defun chris/emms-delete-song () "Deletes files in the emms browser by default. Maybe I'll have a yes or no thingy..." (interactive) (if (yes-or-no-p "delete the file too?") (emms-browser-remove-tracks t) (emms-browser-remove-tracks))) :general (chris/leader-keys :states 'normal :keymaps 'override "mo" 'emms "ml" 'emms-browser "mp" 'emms-pause "ma" 'emms-add-dired "mr" 'emms-toggle-repeat-track "mn" 'emms-next "mb" 'emms-previous "m]" 'emms-seek-forward "m[" 'emms-seek-backward) (general-def 'normal emms-playlist-mode-map "q" 'bury-buffer "d" 'emms-playlist-mode-kill-track "D" 'emms-playlist-mode-goto-dired-at-point) (general-def 'normal emms-browser-mode-map "q" 'bury-buffer "d" 'chris/emms-delete-song "D" 'emms-browser-view-in-dired)) (use-package transmission :commands (transmission) :config (if (string-equal (system-name) "archdesktop") (setq transmission-host "home.cochrun.xyz" transmission-rpc-path "/transmission/rpc" transmission-refresh-modes '(transmission-mode transmission-files-mode transmission-info-mode transmission-peers-mode)) (setq transmission-host "192.168.1.2" transmission-rpc-path "/transmission/rpc" transmission-refresh-modes '(transmission-mode transmission-files-mode transmission-info-mode transmission-peers-mode))) :general (chris/leader-keys :states 'normal :keymaps 'override "ot" 'transmission)) (use-package auth-source-pass :defer 1 :config (auth-source-pass-enable)) (use-package pass :defer 1) (use-package password-store :after pass :general (chris/leader-keys "sp" 'password-store-copy)) (use-package password-store-otp :after password-store :general (chris/leader-keys "st" 'password-store-otp-token-copy)) (use-package plz :ensure t) (use-package ement :ensure t :config (setq ement-room-images t ement-save-sessions nil) :general (general-def 'normal ement-room-mode-map "q" 'bury-buffer "RET" 'ement-room-send-message "r" 'ement-room-send-reply "gr" 'ement-room-sync "R" 'ement-room-send-reaction) (chris/leader-keys "oM" 'ement-list-rooms)) (use-package mastodon :config (setq mastodon-instance-url "https://mastodon.online" mastodon-active-user "chriscochrun") :general (chris/leader-keys "oF" 'mastodon) (general-def 'normal mastodon-mode-map :states 'normal "q" 'bury-buffer "p" 'mastodon-toot "r" 'mastodon-tl--update "b" 'mastodon-toot--toggle-boost "H" 'mastodon-tl--get-home-timeline "F" 'mastodon-tl--get-federated-timeline "v" 'chris/elfeed-bongo-insert-item "N" 'mastodon-notifications--timeline)) (use-package languagetool :ensure t :defer t :commands (languagetool-check languagetool-clear-suggestions languagetool-correct-at-point languagetool-correct-buffer languagetool-set-language languagetool-server-mode languagetool-server-start languagetool-server-stop) :config (setq languagetool-java-arguments '("-Dfile.encoding=UTF-8") languagetool-console-command "/home/chris/.emacs.d/languagetool/languagetool-commandline.jar" languagetool-server-command "/home/chris/.emacs.d/languagetool/languagetool-server.jar")) (use-package qrencode) ;; Reduce rendering/line scan work for Emacs by not rendering cursors or regions ;; in non-focused windows. (setq-default cursor-in-non-selected-windows nil) (setq highlight-nonselected-windows nil) ;; More performant rapid scrolling over unfontified regions. May cause brief ;; spells of inaccurate syntax highlighting right after scrolling, which should ;; quickly self-correct. (setq fast-but-imprecise-scrolling t) ;; Don't ping things that look like domain names. (setq ffap-machine-p-known 'reject) ;; Emacs "updates" its ui more often than it needs to, so we slow it down ;; slightly from 0.5s: (setq idle-update-delay 1.0) ;; Font compacting can be terribly expensive, especially for rendering icon ;; fonts on Windows. Whether disabling it has a notable affect on Linux and Mac ;; hasn't been determined, but we inhibit it there anyway. This increases memory ;; usage, however! ;; (setq inhibit-compacting-font-caches t) ;; Introduced in Emacs HEAD (b2f8c9f), this inhibits fontification while ;; receiving input, which should help with performance while scrolling. (setq redisplay-skip-fontification-on-input t) (setq gc-cons-threshold (* 32 1024 1024)) (setq garbage-collection-messages nil) (use-package gcmh :ensure t :init (gcmh-mode) :config (setq gcmh-idle-delay 2 gcmh-high-cons-threshold (* 128 1024 1024) ; 128mb gcmh-verbose nil)) (setq warning-suppress-types '((comp)))