(setq user-full-name "Colin Powell" user-mail-address "colin@unbl.ink") (setq ivy-read-action-function #'ivy-hydra-read-action) (setq doom-theme 'kaolin-galaxy doom-font (font-spec :family "JetBrains Mono NL" :size 14 :weight 'semi-light) doom-big-font (font-spec :family "JetBrains Mono NL" :size 18) doom-variable-pitch-font (font-spec :family "Overpass" :size 16)) ;; 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! (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 "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 wttrin-default-cities '("Castine, ME" "San Francisco" "Thessaloniki")) (setq wttrin-default-accept-language '("Accept-Language" . "en-US")) (map! (:leader (:prefix "o" :desc "(W)eather" "W" #'wttrin))) (setq libmpdel-hostname "mpd.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-ttrss-maxsize 200) ;; bigger than 200 is invalid (setq elfeed-feeds '("ttrss+https://powellc:hT7nPKAHa^fYwXZ*@reader.unbl.ink")) (setq elfeed-log-level 'debug) (elfeed-protocol-enable) ;; Schedule feed update for every day at 3PM (run-at-time "15 min" nil 'elfeed-update) (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) ;; PlantUML is awesome for quick diagrams (add-to-list 'auto-mode-alist '("\\.plantuml\\'" . plantuml-mode)) ;; Timezone location strings at http://worldtime.io (setq display-time-world-list '(("America/Los_Angeles" "San Francisco") ("America/Tegucigalpa" "Tegucigalpa") ("America/New_York" "New York") ("Europe/London" "London") ("Europe/Warsaw" "Warsaw") ("Europe/Kiev" "Lviv"))) (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) (add-hook 'org-mode-hook #'doom-disable-line-numbers-h) (after! org (setq org-directory (expand-file-name "~/var/org/") org-agenda-files (file-expand-wildcards "~/var/org/2020-*") org-pretty-entities t org-agenda-dim-blocked-tasks nil org-log-done 'time org-hide-emphasis-markers t org-fontify-whole-heading-line t org-fontify-done-headline t org-fontify-quote-and-verse-blocks t org-ellipsis "…" org-image-actual-width '(600) org-capture-templates '(("i" "Send to inbox" entry (file "~/var/org/inbox.org") "* TODO %?\n")) org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "MAYBE(m)" "|" "DONE(d)" "WONTDO(w)")) org-modules '(ol-eshell ol-notmuch ob-eval ob-exp ob-http org-id))) ;; Don’t display git gutter in org mode ;; With tree folding, it's pretty much useless (after! git-gutter (setq git-gutter:disabled-modes '(org-mode image-mode))) ;; Refiling (setq org-refile-targets '(("~/var/org/inbox.org" :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/inbox.org") (defun +open-inbox-file () (interactive) "Opens the inbox file" (find-file +inbox-file)) (map! :leader :desc "Open inbox" "I" #'+open-inbox-file :desc "Save all org buffers" "A" #'org-save-all-org-buffers) (setq org-agenda-span 3 org-agenda-start-day "1d") (defun +show-agenda () (interactive) (delete-other-windows) (with-popup-rules! nil (org-agenda-list) (calendar)) (other-window 1) (split-window-vertically) (other-window 1) (find-file +todo-file)) (setq org-roam-directory "~/var/org/") (setq org-fc-directories "~/var/org/") (require 'org-fc-hydra) (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) ;(load! "+mail") ;; Mail stuff ; Use w3m to parse HTML email (setq mm-text-html-renderer 'w3m) (setq w3m-fill-column 88) ; Kill email message buffers when you close them (setq message-kill-buffer-on-exit t) (setq message-auto-save-directory "~/Mail/colin@unbl.ink/Drafts/") (setq message-directory "~/Mail/colin@unbl.ink/") ;;; Setup sending email with msmtp ;; 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) (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 $*" "djsh" "DJANGO_SETTINGS_MODULE=ff.settings.ci python manage.py shell_plus" "dj" "DJANGO_SETTINGS_MODULE=ff.settings.ci python manage.py $*" "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")) ;(add-hook 'python-mode-hook 'eglot-ensure) (setq mastodon-instance-url "https://mastodon.technology") (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)) (use-package! slack :commands (slack-start) :init (setq slack-buffer-emojify t) (setq slack-prefer-current-team t) :config (slack-register-team :name "15five" :token (auth-source-pick-first-password :host "15five.slack.com" :user "colin.powell@15five.com") :subscribed-channels '(squad-admin water-cooler)) (slack-register-team :name "RAB" :token (auth-source-pick-first-password :host "randomaccessbrewery.slack.com" :user "colin@onec.me") :subscribed-channels '(the_taps random)) (evil-define-key 'normal slack-info-mode-map ",u" 'slack-room-update-messages) (evil-define-key 'normal slack-mode-map ",c" 'slack-buffer-kill ",ra" 'slack-message-add-reaction ",rr" 'slack-message-remove-reaction ",rs" 'slack-message-show-reaction-users ",pl" 'slack-room-pins-list ",pa" 'slack-message-pins-add ",pr" 'slack-message-pins-remove ",mm" 'slack-message-write-another-buffer ",me" 'slack-message-edit ",md" 'slack-message-delete ",u" 'slack-room-update-messages ",2" 'slack-message-embed-mention ",3" 'slack-message-embed-channel "\C-n" 'slack-buffer-goto-next-message "\C-p" 'slack-buffer-goto-prev-message) (evil-define-key 'normal slack-edit-message-mode-map ",k" 'slack-message-cancel-edit ",s" 'slack-message-send-from-buffer ",2" 'slack-message-embed-mention ",3" 'slack-message-embed-channel)) (use-package! alert :commands (alert) :init (setq alert-default-style 'libnotify)) (map! :leader (:prefix "o" (:prefix ("s" . "+slack") :desc "Slack channels" "S" #'slack-start :desc "Slack channels" "s" #'slack-channel-select :desc "Slack IMs" "i" #'slack-im-select :desc "Slack groups" "g" #'slack-group-select :desc "Slack threads" "t" #'slack-all-threads))) (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)) ;;(add-hook 'magit-mode-hook #'doom-disable-line-numbers-h) (setq +magit-hub-features t ;; I want the PR/issue stuff too! +magit-hub-enable-by-default t) ;; And I want it on by default! (after! magit (magit-wip-after-save-mode t) (magit-wip-after-apply-mode t) (setq magit-save-repository-buffers 'dontask magit-circleci-token "097bf0dd808ad9103d489844e37cecffdf967837" 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. (setq lsp-enable-links nil) (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))