Files
dotfiles/emacs/.doom.d/config.el

386 lines
13 KiB
EmacsLisp
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(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)))
;; Dont 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))