(setq user-full-name "Colin Powell" user-mail-address "colin@unbl.ink") ;;(setq ivy-read-action-function #'ivy-hydra-read-action) (defun file-notify-rm-all-watches () "Remove all existing file notification watches from Emacs." (interactive) (maphash (lambda (key _value) (file-notify-rm-watch key)) file-notify-descriptors)) (setq doom-theme 'moe-dark doom-font (font-spec :family "IBM Plex Mono" :size 13 :weight 'regular) doom-big-font (font-spec :family "IBM Plex Mono" :size 17 :weight 'regular) doom-variable-pitch-font (font-spec :family "Overpass" :size 12)) ;; Applies to current frame ;(set-frame-parameter nil 'internal-border-width 10) ; applies to the current frame ;; If we create new frames (via emacsclient) this will do the trick ;(add-to-list 'default-frame-alist '(internal-border-width . 10)) (nyan-mode) ;; progress in the form of a rainbow cat. (add-hook 'after-init-hook #'global-emojify-mode) ;; emojis?! (add-hook 'prog-mode-hook #'goto-address-mode) ;; linify links! (setq eww-search-prefix "https://search.unbl.ink/?q=") (map! ;; Easier window movement :n "C-h" 'evil-window-left :n "C-j" 'evil-window-down :n "C-k" 'evil-window-up :n "C-l" 'evil-window-right (:map evil-treemacs-state-map "C-h" 'evil-window-left "C-l" 'evil-window-right) :leader (:prefix "f" :desc "Find file in dotfiles" "t" #'+hlissner/find-in-dotfiles :desc "Browse dotfiles" "T" #'+hlissner/browse-dotfiles) (:prefix "o" :desc "(H)ckrnews" "H" #'hackernews :desc "(R)SS" "R" #'=rss :desc "(M)ail" "M" #'=notmuch :desc "(L)obste.rs" "L" #'ivy-lobsters) (:prefix "b" :desc "Black format buffer" "f" #'blacken-buffer :desc "isort buffer" "I" #'py-isort-buffer :desc "Links in buffer" "l" #'ace-link-org) (:prefix "s" :desc "Copy link hints" "c" #'link-hint-copy-link :desc "Search the web" "w" #'web-search :desc "Goto URL in eww" "u" #'eww-browse-url :desc "Search in eww" "3" #'eww-search-words :desc "Search all the things" "g" #'deadgrep)) (setq libmpdel-hostname "mpd.play.unbl.ink") (defun mpdel-playlist-play () "Start playing the song at point." (interactive) (if (derived-mode-p 'mpdel-playlist-current-playlist-mode) (libmpdel-play-song (navigel-entity-at-point)) (mpdel-core-insert-current-playlist))) (map! :leader (:prefix "-" :desc "MPD Open playlist" "-" #'mpdel-playlist-open :desc "MPD Remove at point" "d" #'mpdel-playlist-delete :desc "MPD Start at point" "s" #'mpdel-playlist-play :desc "MPD Next track" "n" #'libmpdel-playback-next :desc "MPD Previous track" "p" #'libmpdel-playback-previous)) (setq elfeed-protocol-fever-maxsize 100) (setq elfeed-feeds '(("fever+https://secstate@rss.unbl.ink" :api-url "https://rss.unbl.ink/fever/" :password "delegator flaxseed request washer" :autotags '(("rss.unbl.ink"))))) ;(setq elfeed-protocol-log-trace t) (setq elfeed-protocol-fever-maxsize 50) ;(setq elfeed-log-level 'debug) (elfeed-protocol-enable) (map! :leader (:prefix "r" :desc "Open Elfeed" "r" #'elfeed :desc "Update Elfeed" "u" #'elfeed-update)) ;; Schedule feed update for every 15 minutes (run-at-time 300 300 (lambda () (when (= elfeed-curl-queue-active 0) (elfeed-update)))) ;;;;; Database auto-save ;; Save elfeed db automatically, because if Emacs crashes or is killed (which happens to me ;; occasionally, especially since I develop packages in a single instance), we'd lose the db ;; updates not saved. (unless (cl-loop for timer in timer-idle-list thereis (equal (aref timer 5) #'elfeed-db-save)) (run-with-idle-timer 400 'repeat #'elfeed-db-save)) (setq elfeed-search-filter "@2-days-ago +unread") (defun elfeed-search-format-date (date) (format-time-string "%Y-%m-%d %H:%M" (seconds-to-time date))) ; Serif font in Elfeed (add-hook! 'elfeed-mode-hook 'variable-pitch-mode) (add-hook! 'elfeed-show-mode-hook (text-scale-set 1.2)) (defun unfill-paragraph () "Takes a multi-line paragraph and makes it into a single line of text." (interactive) (let ((fill-column (point-max))) (fill-paragraph nil))) (define-key global-map "\M-z" 'unfill-paragraph) (flycheck-define-checker vale "A checker for prose" :command ("vale" "--output" "line" source) :standard-input nil :error-patterns ((error line-start (file-name) ":" line ":" column ":" (id (one-or-more (not (any ":")))) ":" (message) line-end)) :modes (markdown-mode org-mode text-mode) ) (add-to-list 'flycheck-checkers 'vale 'append) (setq +format-on-save-enabled-modes '(not emacs-lisp-mode ; elisp's mechanisms are good enough sql-mode ; sqlformat is currently broken tex-mode ; latexindent is broken org-mode html-mode latex-mode)) (load! "+agenda-fix") (defun vulpea-agenda-files-update (&rest _) (setq org-agenda-files vulpea-project-files)) (advice-add 'org-agenda :before #'vulpea-agenda-files-update) (advice-add 'org-todo-list :before #'vulpea-agenda-files-update) (add-hook 'org-mode-hook #'doom-disable-line-numbers-h) (after! org (setq org-directory (expand-file-name "~/var/org/") org-ellipsis "…" org-image-actual-width '(600) org-log-done 'time org-fontify-quote-and-verse-blocks t org-agenda-dim-blocked-tasks nil org-pretty-entities t org-fancy-priorities-list '("🅰" "🅱" "🅲" "🅳" "🅴") org-modules '(ol-eshell ol-notmuch ob-eval ob-exp ob-http org-id))) ;; Refiling (setq org-refile-targets '((vulpea-project-files :maxlevel . 9))) (setq org-outline-path-complete-in-steps nil) ; Refile in a single go (setq org-refile-use-outline-path t) ; Show full paths for refiling (setq +inbox-file "~/var/org/index.org") (defun +open-inbox-file () (interactive) "Opens the inbox file" (find-file +inbox-file)) (map! :leader :desc "Open inbox" "I" #'+open-inbox-file :desc "Open today" "d" #'org-roam-dailies-goto-today :desc "Save all org buffers" "A" #'org-save-all-org-buffers) (setq org-roam-directory "~/var/org/") (setq org-roam-dailies-directory "dailies") (require 'justify-kp) ;(setq nov-text-width t) (setq nov-text-width 100) (defun my-nov-window-configuration-change-hook () (my-nov-post-html-render-hook) (remove-hook 'window-configuration-change-hook 'my-nov-window-configuration-change-hook t)) (defun my-nov-post-html-render-hook () (if (get-buffer-window) (let ((max-width (pj-line-width)) buffer-read-only) (save-excursion (goto-char (point-min)) (while (not (eobp)) (when (not (looking-at "^[[:space:]]*$")) (goto-char (line-end-position)) (when (> (shr-pixel-column) max-width) (goto-char (line-beginning-position)) (pj-justify))) (forward-line 1)))) (add-hook 'window-configuration-change-hook 'my-nov-window-configuration-change-hook nil t))) (add-hook 'nov-post-html-render-hook 'my-nov-post-html-render-hook) (defun my-nov-font-setup () (face-remap-add-relative 'variable-pitch :family "Noto Serif Regular" :height 1.0 :size 16)) (add-hook 'nov-mode-hook 'my-nov-font-setup) (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)) ;(add-hook 'nov-mode-hook 'variable-pitch-mode) (setq mm-text-html-renderer 'w3m) (setq w3m-fill-column 88) (setq message-kill-buffer-on-exit t) (setq message-auto-save-directory "~/Mail/colin@unbl.ink/Drafts/") (setq message-directory "~/Mail/colin@unbl.ink/") ;; sendmail-program "/usr/local/bin/msmtpq" <--- this doesn't work as advertised right now (setq send-mail-function 'sendmail-send-it sendmail-program "/usr/local/bin/msmtp" mail-specify-envelope-from t message-sendmail-f-is-evil t message-sendmail-envelope-from 'header message-sendmail-extra-arguments '("--read-envelope-from") mail-envelope-from 'header) (setq notmuch-saved-searches '((:name "inbox" :query "tag:inbox" :key "i") (:name "unread" :query "tag:inbox and tag:unread" :key "u") (:name "jira" :query "tag:jira and date:yesterday..today" :key "j") (:name "github" :query "tag:github and date:yesterday..today" :key "g"))) (after! notmuch (set-popup-rule! "^\\*notmuch*" :ignore t) ) (map! :leader (:prefix "e" :desc "(s)end queued mail" "s" #'smtpmail-send-queued-mail :desc "Open (i)nbox" "i" #'=notmuch :desc "Open (n)otmuch" "n" #'notmuch :desc "(C)ompose mail" "c" #'notmuch-mua-new-mail)) (after! eshell (set-eshell-alias! "djtest" "DJANGO_SETTINGS_MODULE=ff.settings.ci python manage.py test $*" "djpytest" "DJANGO_SETTINGS_MODULE=ff.settings.ci pytest --reuse-db --black --flake8 --isort --durations=3 $*" "ffsh" "python ~/src/github.com/15five/fifteen5/manage.py shell_plus" "ffdev" "ssh dev-ff.local " "f" "(other-window 1) && find-file $1" "l" "ls -lh" "d" "dired $1" "gl" "(call-interactively 'magit-log-current)" "gs" "magit-status" "gc" "magit-commit")) (setq lsp-lens-enable 1 lsp-ui-sideline-enable 1 lsp-enable-links 1 lsp-headerline-breadcrumb-enable 1 lsp-modeline-code-actions-enable 1 lsp-modeline-diagnostics-enable 1 lsp-completion-show-detail 1 lsp-file-watch-threshold nil ) (use-package lsp-mode :commands lsp :diminish lsp-mode :hook (elixir-mode . lsp) :init (add-to-list 'exec-path "~/.emacs.d/var/elixir-ls")) (setq mastodon-instance-url "https://fosstodon.org" mastodon-active-user "colin@unbl.ink") (map! :leader (:prefix "=" :desc "Open mastodon" "=" #'mastodon :desc "Update Mastodon timeline" "u" #'mastodon-tl--update :desc "More Mastodon timeline" "m" #'mastodon-tl--more :desc "Toot to Mastodon" "t" #'mastodon-toot)) (load! "beancount") (require 'beancount) (add-to-list 'auto-mode-alist '("\\.beancount\\'" . beancount-mode)) (define-derived-mode pandoc-view-mode markdown-mode "pandoc-view-mode" "View pandoc processing of docx file using markdown mode." (erase-buffer) (let* ((pandoc (executable-find "pandoc"))) (insert (shell-command-to-string (concat pandoc " --wrap=none " (shell-quote-argument (buffer-file-name)) " -t markdown")))) (not-modified) (read-only-mode t)) (add-to-list 'auto-mode-alist '("\\.docx\\'" . pandoc-view-mode)) (after! magit (magit-wip-after-save-mode t) (magit-wip-after-apply-mode t) (setq magit-save-repository-buffers 'dontask magit-repository-directories '(("~/src/" . 3) ("~/.dotfiles/" . 0)) magit-popup-display-buffer-action nil ;; Not sure why this is here, wonder what it does magit-display-file-buffer-function #'switch-to-buffer-other-window magithub-clone-default-directory "~/src" ;; I want my stuff to clone to ~/projects magithub-preferred-remote-method 'ssh_url)) ;; HTTPS cloning is awful, i authenticate with ssh keys. ; Show gravatars in magit (setq magit-revision-show-gravatars '("^Author: " . "^Commit: ")) (when (require 'openwith nil 'noerror) (setq openwith-associations (list (list (openwith-make-extension-regexp '("mpg" "mpeg" "mp3" "mp4" "avi" "wmv" "wav" "mov" "flv" "ogm" "ogg" "mkv")) "vlc" '(file)) (list (openwith-make-extension-regexp '("pdf" "ps" "ps.gz" "dvi")) "zathura" '(file)) )) (openwith-mode 1)) (setq org-reveal-root "file:///path-to-reveal.js") (setq org-reveal-title-slide nil) ;(require 'chatgpt-shell)