Initial commit.
This commit is contained in:
1520
README.org
Normal file
1520
README.org
Normal file
File diff suppressed because it is too large
Load Diff
1520
config.org
Normal file
1520
config.org
Normal file
File diff suppressed because it is too large
Load Diff
142
extra/email.org
Normal file
142
extra/email.org
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
#+PROPERTY: header-args :tangle email.el
|
||||||
|
|
||||||
|
Incoming email is handled by [[https://notmuchmail.org][notmuch]]. Outgoing is via [[https://github.com/marlam/msmtp][msmtp]]
|
||||||
|
|
||||||
|
This is a pretty simple implementation without a lot of search queries, and
|
||||||
|
list handling. As I get more comfortable with using emacs as an email client
|
||||||
|
I'll try to get fancier.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
;; Email/notmuch settings -*- lexical-binding: t; -*-
|
||||||
|
(use-package notmuch
|
||||||
|
:init
|
||||||
|
(autoload 'notmuch "notmuch" "notmuch mail" t)
|
||||||
|
:config
|
||||||
|
(define-key notmuch-show-mode-map "d"
|
||||||
|
(lambda ()
|
||||||
|
"toggle deleted tag for message"
|
||||||
|
(interactive)
|
||||||
|
(if (member "deleted" (notmuch-show-get-tags))
|
||||||
|
(notmuch-show-tag (list "-deleted"))
|
||||||
|
(notmuch-show-tag (list "+deleted")))))
|
||||||
|
|
||||||
|
(define-key notmuch-search-mode-map "d"
|
||||||
|
(lambda ()
|
||||||
|
"toggle deleted tag for message"
|
||||||
|
(interactive)
|
||||||
|
(if (member "deleted" (notmuch-search-get-tags))
|
||||||
|
(notmuch-search-tag (list "-deleted"))
|
||||||
|
(notmuch-search-tag (list "+deleted")))))
|
||||||
|
|
||||||
|
(define-key notmuch-tree-mode-map "d"
|
||||||
|
(lambda ()
|
||||||
|
"toggle deleted tag for message"
|
||||||
|
(interactive)
|
||||||
|
(if (member "deleted" (notmuch-tree-get-tags))
|
||||||
|
(notmuch-tree-tag (list "-deleted"))
|
||||||
|
(notmuch-tree-tag (list "+deleted"))))))
|
||||||
|
|
||||||
|
|
||||||
|
;; Saved searches
|
||||||
|
(setq notmuch-saved-searches '((:name "cheapbsd"
|
||||||
|
:query "tag:inbox and tag:cheapbsd"
|
||||||
|
:count-query "tag:inbox and tag:cheapbsd and tag:unread")
|
||||||
|
(:name "icloud"
|
||||||
|
:query "tag:inbox and tag:icloud"
|
||||||
|
:count-query "tag:inbox and tag:icloud and tag:unread")
|
||||||
|
(:name "sdf"
|
||||||
|
:query "tag:inbox and tag:sdf"
|
||||||
|
:count-query "tag:inbox and tag:sdf and tag:unread")))
|
||||||
|
|
||||||
|
(setq mml-secure-openpgp-sign-with-sender t)
|
||||||
|
|
||||||
|
;; Sign messages by default.
|
||||||
|
(add-hook 'message-setup-hook 'mml-secure-sign-pgpmime)
|
||||||
|
|
||||||
|
;; Use msmtp
|
||||||
|
(setq send-mail-function 'sendmail-send-it
|
||||||
|
sendmail-program "msmtp"
|
||||||
|
mail-specify-envelope-from t
|
||||||
|
message-sendmail-envelope-from 'header
|
||||||
|
mail-envelope-from 'header)
|
||||||
|
|
||||||
|
(defun message-recipients ()
|
||||||
|
"Return a list of all recipients in the message, looking at TO, CC and BCC.
|
||||||
|
|
||||||
|
Each recipient is in the format of `mail-extract-address-components'."
|
||||||
|
(mapcan (lambda (header)
|
||||||
|
(let ((header-value (message-fetch-field header)))
|
||||||
|
(and
|
||||||
|
header-value
|
||||||
|
(mail-extract-address-components header-value t))))
|
||||||
|
'("To" "Cc" "Bcc")))
|
||||||
|
|
||||||
|
(defun message-all-epg-keys-available-p ()
|
||||||
|
"Return non-nil if the pgp keyring has a public key for each recipient."
|
||||||
|
(require 'epa)
|
||||||
|
(let ((context (epg-make-context epa-protocol)))
|
||||||
|
(catch 'break
|
||||||
|
(dolist (recipient (message-recipients))
|
||||||
|
(let ((recipient-email (cadr recipient)))
|
||||||
|
(when (and recipient-email (not (epg-list-keys context recipient-email)))
|
||||||
|
(throw 'break nil))))
|
||||||
|
t)))
|
||||||
|
|
||||||
|
(defun message-sign-encrypt-if-all-keys-available ()
|
||||||
|
"Add MML tag to encrypt message when there is a key for each recipient.
|
||||||
|
|
||||||
|
Consider adding this function to `message-send-hook' to
|
||||||
|
systematically send encrypted emails when possible."
|
||||||
|
(when (message-all-epg-keys-available-p)
|
||||||
|
(mml-secure-message-sign-encrypt)))
|
||||||
|
|
||||||
|
(add-hook 'message-send-hook #'message-sign-encrypt-if-all-keys-available)
|
||||||
|
|
||||||
|
(setq notmuch-crypto-process-mime t)
|
||||||
|
|
||||||
|
(defvar notmuch-hello-refresh-count 0)
|
||||||
|
|
||||||
|
(defun notmuch-hello-refresh-status-message ()
|
||||||
|
(let* ((new-count
|
||||||
|
(string-to-number
|
||||||
|
(car (process-lines notmuch-command "count"))))
|
||||||
|
(diff-count (- new-count notmuch-hello-refresh-count)))
|
||||||
|
(cond
|
||||||
|
((= notmuch-hello-refresh-count 0)
|
||||||
|
(message "You have %s messages."
|
||||||
|
(notmuch-hello-nice-number new-count)))
|
||||||
|
((> diff-count 0)
|
||||||
|
(message "You have %s more messages since last refresh."
|
||||||
|
(notmuch-hello-nice-number diff-count)))
|
||||||
|
((< diff-count 0)
|
||||||
|
(message "You have %s fewer messages since last refresh."
|
||||||
|
(notmuch-hello-nice-number (- diff-count)))))
|
||||||
|
(setq notmuch-hello-refresh-count new-count)))
|
||||||
|
|
||||||
|
(add-hook 'notmuch-hello-refresh-hook 'notmuch-hello-refresh-status-message)
|
||||||
|
|
||||||
|
(defun color-inbox-if-unread () (interactive)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(let ((cnt (car (process-lines "notmuch" "count" "tag:inbox and tag:unread"))))
|
||||||
|
(when (> (string-to-number cnt) 0)
|
||||||
|
(save-excursion
|
||||||
|
(when (search-forward "inbox" (point-max) t)
|
||||||
|
(let* ((overlays (overlays-in (match-beginning 0) (match-end 0)))
|
||||||
|
(overlay (car overlays)))
|
||||||
|
(when overlay
|
||||||
|
(overlay-put overlay 'face '((:inherit bold) (:foreground "green")))))))))))
|
||||||
|
(add-hook 'notmuch-hello-refresh-hook 'color-inbox-if-unread)
|
||||||
|
|
||||||
|
(custom-set-variables
|
||||||
|
;; custom-set-variables was added by Custom.
|
||||||
|
;; If you edit it by hand, you could mess it up, so be careful.
|
||||||
|
;; Your init file should contain only one such instance.
|
||||||
|
;; If there is more than one, they won't work right.
|
||||||
|
'(notmuch-search-oldest-first nil))
|
||||||
|
(custom-set-faces)
|
||||||
|
;; custom-set-faces was added by Custom.
|
||||||
|
;; If you edit it by hand, you could mess it up, so be careful.
|
||||||
|
;; Your init file should contain only one such instance.
|
||||||
|
;; If there is more than one, they won't work right.
|
||||||
|
#+end_src
|
||||||
64
extra/feed.org
Normal file
64
extra/feed.org
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#+PROPERTY: header-args :tangle "feed.el" :noweb yes
|
||||||
|
|
||||||
|
I get a lot of my news, and updates via Atom/RSS feeds. If I'm going to
|
||||||
|
browse them in emacs I use elfeed.
|
||||||
|
|
||||||
|
#+name: header
|
||||||
|
#+begin_src emacs-lisp :exports none
|
||||||
|
;;; elfeed -- Just my elfeed config. -*- lexical-binding: t; -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Nothing yet.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: footer
|
||||||
|
#+begin_src emacs-lisp :exports none
|
||||||
|
(provide 'feed)
|
||||||
|
;;; feed.el ends here
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: feed-src
|
||||||
|
#+begin_src emacs-lisp :exports code
|
||||||
|
|
||||||
|
(use-package elfeed
|
||||||
|
:defer t
|
||||||
|
:bind
|
||||||
|
(("C-c F" . elfeed)))
|
||||||
|
|
||||||
|
(use-package elfeed-org
|
||||||
|
:after (elfeed)
|
||||||
|
:config
|
||||||
|
(elfeed-org)
|
||||||
|
(setq rmh-elfeed-org-files (list "~/.emacs.d/extra/elfeed.org")))
|
||||||
|
|
||||||
|
(use-package elfeed-tube
|
||||||
|
:after (elfeed)
|
||||||
|
:config
|
||||||
|
(elfeed-tube-setup)
|
||||||
|
:bind (:map elfeed-show-mode-map
|
||||||
|
("F" . elfeed-tube-fetch)
|
||||||
|
([remap save-buffer] . elfeed-tube-save)
|
||||||
|
:map elfeed-search-mode-map
|
||||||
|
("F" . elfeed-tube-fetch)
|
||||||
|
([remap save-buffer] . elfeed-tube-save)))
|
||||||
|
|
||||||
|
(use-package mpv
|
||||||
|
:ensure (:host github :repo "kljohann/mpv.el"))
|
||||||
|
|
||||||
|
(use-package elfeed-tube-mpv
|
||||||
|
:after (elfeed-tube mpv)
|
||||||
|
:bind (:map elfeed-show-mode-map
|
||||||
|
("C-c C-f" . elfeed-tube-mpv-follow-mode)
|
||||||
|
("C-c C-w" . elfeed-tube-mpv-where)))
|
||||||
|
|
||||||
|
(use-package elfeed-goodies
|
||||||
|
:after (elfeed)
|
||||||
|
:config
|
||||||
|
(elfeed-goodies/setup))
|
||||||
|
|
||||||
|
<<footer>>
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS: feed-src
|
||||||
|
: feed
|
||||||
51
extra/social.org
Normal file
51
extra/social.org
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#+PROPERTY: header-args :tangle "social.el" :exports code
|
||||||
|
|
||||||
|
* Mastodon, and other tidbits
|
||||||
|
|
||||||
|
#+name: header
|
||||||
|
#+begin_src emacs-lisp :exports none
|
||||||
|
;;; social -- Provides social features -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Only provides Mastodon, and discord presence currently.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS: header
|
||||||
|
|
||||||
|
** Mastodon
|
||||||
|
|
||||||
|
Just a little package for browsing mastodon. I don't use it much, but
|
||||||
|
it's deferred and doesn't take much space.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
<<header>>
|
||||||
|
|
||||||
|
(use-package mastodon
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
(setq mastodon-instance-url "https://mastodon.social"
|
||||||
|
mastodon-active-user "xulfer"))
|
||||||
|
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Ugh... Discord
|
||||||
|
|
||||||
|
Not a big discord user, but when I do I might as well flash the editor.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
;; Well just in case there is an urge to hop on discord... :(
|
||||||
|
(use-package elcord
|
||||||
|
:config
|
||||||
|
(elcord-mode))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: footer
|
||||||
|
#+begin_src emacs-lisp :exports none
|
||||||
|
;;; social.el ends here
|
||||||
|
|
||||||
|
(provide 'social)
|
||||||
|
|
||||||
|
#+end_src
|
||||||
BIN
img/preview.png
Normal file
BIN
img/preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Reference in New Issue
Block a user