user-full-name "Eshel Yaron"
;; my email address
user-mail-address "me@eshelyaron.com"
+ mail-user-agent 'gnus-user-agent
+ read-mail-command 'gnus
;; direct Custom definitions to some file and forget about it
custom-file (expand-file-name "custom.el" user-emacs-directory)
;; silence native compilation warnings
vc-follow-symlinks t
;; jump from .c to .h files with find-sibling-file
find-sibling-rules '(("\\([^/]+\\)\\.c\\'" "\\1.h"))
- message-alternative-emails (regexp-opt '("eshelshay.yaron@gmail.com"
- "me@eshelyaron.com"
- "eshel@swi-prolog.org"
- "eshel.yaron@student.uva.nl"))
- ;; set function for sending email
- send-mail-function #'esy/smtp-send-it
- message-send-mail-function #'esy/smtp-send-it
- ;; set email user agent
- mail-user-agent 'gnus-user-agent
- read-mail-command 'gnus
- ;; make Gnus not prompt as much
- gnus-expert-user t
- ;; make Gnus read the dribble file on startup without prompting
- gnus-always-read-dribble-file t
- ;; don't break pages in incoming email
- gnus-break-pages nil
- ;; don't show the Gnus startup screen
- gnus-inhibit-startup-message t
- ;; set Gnus backends
- gnus-select-method '(nntp "news.gmane.io")
- gnus-cite-parse-max-size nil
- gnus-face-1 'bold
- gnus-face-2 'gnus-cite-1
- gnus-face-3 'shadow
- gnus-summary-line-format "%1{%U%R%z%}%B%2{%~(form (replace-regexp-in-string \" via .*\" \"\" (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header gnus-tmp-from)))@%} %3{(%&user-date;, %k)%}:%* %s\n"
- gnus-simplify-subject-functions '(gnus-simplify-subject-re)
- gnus-treat-display-smileys nil
- gnus-secondary-select-methods '((nnimap "gmail"
- (nnimap-address "imap.gmail.com")
- (nnimap-server-port "imaps")
- (nnimap-stream ssl))
- (nnimap "me"
- (nnimap-address "mail.eshelyaron.com")
- (nnimap-server-port "imaps")
- (nnimap-stream ssl))
- (nnimap "swi"
- (nnimap-address "mail.swi-prolog.com")
- (nnimap-server-port "imaps")
- (nnimap-stream ssl))
- (nnimap "uva"
- (nnimap-address "outlook.office365.com")
- (nnimap-server-port "imaps")
- (nnimap-stream ssl)
- (nnimap-authenticator xoauth2)))
- ;; simpler message
- gnus-no-groups-message "No new articles"
- ;; don't close other windows when opening Gnus
- gnus-use-full-window nil
- ;; make Gnus handle this content types
- gnus-article-treat-types '("text/plain"
- "text/x-verbatim"
- "text/x-patch"
- "text/html"
- "text/calendar")
- ;; capture calendar events from Gnus to my Org inbox file
- gnus-icalendar-org-capture-file "~/org/inbox.org"
- ;; put calendar events under the Calendar heading
- gnus-icalendar-org-capture-headline '("Calendar")
;; use ISO format for calendar dates
calendar-date-style 'iso
;; maintain legibility of rendered text in HTML mails
shr-color-visible-luminance-min 75
- ;; my Mastodon settings
- mastodon-instance-url "https://emacs.ch"
- mastodon-active-user "eshel"
;; direct Magit to my Git checkouts directory
magit-repository-directories '(("~/checkouts/" . 1))
;; have Dired operations target another visible Dired buffer
vterm-use-vterm-prompt-detection-method t
;; use MPV with EMMS
emms-player-list '(emms-player-mpv)
- ;; free-style numbering plan
- bbdb-phone-style nil
- ;; allow cycling through mail address completion candidate
- bbdb-complete-mail-allow-cycling t
- ;; don't pop up BBDB records after completing mail addresses
- bbdb-completion-display-record nil
eww-auto-rename-buffer 'title
browse-url-browser-function #'eww-browse-url
browse-url-generic-program "open"
"Global Bindings:"
"Function key map translations"
"pixel-scroll-precision-mode"
- "context-menu-mode"))))
- report-emacs-bug-no-explanations t
- submit-emacs-patch-display-help nil)
+ "context-menu-mode")))))
(setq-default indent-tabs-mode nil)
(add-to-list 'load-path (expand-file-name "lisp/" user-emacs-directory))
(autoload 'some-button "some-button" nil t)
-(autoload 'esy-capture "esy-capture" nil t)
(autoload 'pdf-view-mode "pdf-view" nil t)
+(with-eval-after-load 'gnus
+ (require 'esy-comm))
+
;;; Define custom commands
(defvar-keymap transpose-lines-repeat-map
(add-to-list 'org-agenda-custom-commands
'("h" "Holland TODOs" tags-todo "+holland")))
-;;; Outlook OAuth 2.0 setup
-
-(defvar esy/o365-token-last-refresh-time 0)
-(defvar esy/o365-token-directory "~/checkouts/M365-IMAP/")
-
-(add-to-list 'auth-sources (expand-file-name ".authinfo"
- esy/o365-token-directory))
-
-(add-to-list 'savehist-additional-variables 'esy/o365-token-last-refresh-time)
-
-(defun esy/refresh-o365-token ()
- (interactive)
- (files--ensure-directory esy/o365-token-directory)
- (when-let ((default-directory esy/o365-token-directory)
- (token (car (process-lines "python3" "refresh_token.py"))))
- (with-temp-buffer
- (insert "machine smtp.office365.com smtp-auth xoauth2 login eshel.yaron@student.uva.nl port 587 password \""
- token
- "\"\nmachine outlook.office365.com login eshel.yaron@student.uva.nl port imaps password \""
- token
- "\"\n")
- (write-region (point-min) (point-max) ".authinfo"))
- (auth-source-forget-all-cached)))
-
-(defun esy/maybe-refresh-o365-token ()
- (let ((now (float-time)))
- (when (< (* 60 45) (- now esy/o365-token-last-refresh-time))
- (esy/refresh-o365-token)
- (setq esy/o365-token-last-refresh-time now))))
-
-;;; Configure email via `gnus'
-
-(with-eval-after-load 'gnus
- (require 'gnus-icalendar)
- (add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
- (add-hook 'gnus-before-resume-hook #'esy/maybe-refresh-o365-token)
- (add-hook 'gnus-before-startup-hook #'esy/maybe-refresh-o365-token)
- (gnus-icalendar-setup)
- (gnus-icalendar-org-setup)
- (bbdb-initialize 'gnus 'mail 'message))
-
-
-(defvar esy/smtp-accounts
- '(("eshelshay.yaron@gmail.com" . "smtp.gmail.com")
- ("eshel@swi-prolog.org" . "mail.swi-prolog.com")
- ("me@eshelyaron.com" . "mail.eshelyaron.com")
- ("eshel.yaron@student.uva.nl" . "smtp.office365.com")))
-
-(defun esy/mail-from ()
- (without-restriction
- (message-narrow-to-headers)
- (when-let ((from (mail-fetch-field "from")))
- (cadr (mail-extract-address-components from)))))
-
-(defun esy/smtp-send-it ()
- (require 'smtpmail)
- (if-let ((from (esy/mail-from))
- (server (alist-get from esy/smtp-accounts nil nil #'string=)))
- (let ((smtpmail-smtp-user from)
- (smtpmail-smtp-server server)
- (smtpmail-smtp-service 587)
- (smtpmail-stream-type 'starttls)
- (smtpmail-servers-requiring-authorization ".*"))
- (smtpmail-send-it))
- (user-error "Unrecognized FROM address, not sending")))
-
-(with-eval-after-load 'message
- (add-hook 'message-send-hook 'ispell-message))
-
;;; Configure `dired'
(with-eval-after-load 'dired
+++ /dev/null
-;;; esy-capture.el --- capture a new post -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2023 Eshel Yaron
-
-;; Author: Eshel Yaron <me@eshelyaron.com>
-;; Keywords: convenience
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;
-
-;;; Code:
-
-(defvar esy-capture-directory "~/checkouts/eshelyaron.com/draft")
-
-(defvar esy-capture-keywords '("emacs"
- "prolog"
- "language"
- "politics"
- "ai"
- "lisp"))
-
-(defun esy-capture (title subtitle description keywords date)
- (interactive (list (read-string "Title: ")
- (read-string "Subtitle: ")
- (read-string "Description: ")
- (completing-read-multiple "Keywords: " esy-capture-keywords)
- (format-time-string "%F")))
- (find-file (expand-file-name
- (concat date
- "-"
- (downcase (string-join (string-split title (rx (+ (not alnum))) t) "-"))
- ".org")
- esy-capture-directory))
- (insert "#+TITLE: " title "\n"
- "#+SUBTITLE: " subtitle "\n"
- "#+DESCRIPTION: " description "\n"
- "#+KEYWORDS: " (string-join keywords ",") "\n"
- "#+DATE: " date "\n")
- (set-buffer-modified-p nil))
-
-(provide 'esy-capture)
-;;; esy-capture.el ends here
--- /dev/null
+;;; esy-comm.el --- My communication settings -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2023 Eshel Yaron
+
+;; Author: Eshel Yaron <me@eshelyaron.com>
+;; Keywords: comm
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'esy-o365)
+(require 'savehist)
+
+(defvar esy-comm-accounts
+ '(("me"
+ "me@eshelyaron.com" "mail.eshelyaron.com" "mail.eshelyaron.com")
+ ("gmail"
+ "eshelshay.yaron@gmail.com" "imap.gmail.com" "smtp.gmail.com")
+ ("swi"
+ "eshel@swi-prolog.org" "mail.swi-prolog.com" "mail.swi-prolog.com")
+ ("uva"
+ "eshel.yaron@student.uva.nl" "outlook.office365.com" "smtp.office365.com"
+ (nnimap-authenticator xoauth2))))
+
+(defvar esy-comm-summary-line-format
+ (concat "%1{%U%R%z%}%B"
+ "%2{%~(form (replace-regexp-in-string \" via .*\" \"\" (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header gnus-tmp-from)))@%} "
+ "%3{(%&user-date;, %k)%}:%* %s\n"))
+
+(defun esy-comm--mail-from ()
+ (without-restriction
+ (message-narrow-to-headers)
+ (when-let ((from (mail-fetch-field "from")))
+ (cadr (mail-extract-address-components from)))))
+
+(defun esy-comm-send-message ()
+ (require 'smtpmail)
+ (if-let ((from (esy-comm--mail-from))
+ (server (alist-get from
+ (mapcar (pcase-lambda
+ (`(,_ ,car ,_ ,cdr . ,_))
+ (cons car cdr))
+ esy-comm-accounts)
+ nil nil #'string=)))
+ (let ((smtpmail-smtp-user from)
+ (smtpmail-smtp-server server)
+ (smtpmail-smtp-service 587)
+ (smtpmail-stream-type 'starttls)
+ (smtpmail-servers-requiring-authorization ".*"))
+ (smtpmail-send-it))
+ (user-error "Unrecognized FROM address, not sending")))
+
+(setq
+ ;; sendmail.el
+ send-mail-function #'esy-comm-send-message
+
+ ;; Message
+ message-send-mail-function #'esy-comm-send-message
+ message-alternative-emails (regexp-opt (mapcar #'cadr esy-comm-accounts))
+
+ ;; Gnus
+ gnus-expert-user t
+ gnus-always-read-dribble-file t
+ gnus-break-pages nil
+ gnus-inhibit-startup-message t
+ gnus-cite-parse-max-size nil
+ gnus-face-1 'bold
+ gnus-face-2 'gnus-cite-1
+ gnus-face-3 'shadow
+ gnus-summary-line-format esy-comm-summary-line-format
+ gnus-simplify-subject-functions '(gnus-simplify-subject-re)
+ gnus-treat-display-smileys nil
+ gnus-select-method '(nntp "news.gmane.io")
+ gnus-secondary-select-methods (mapcar
+ (pcase-lambda
+ (`(,name ,_ ,address ,_ . ,tail))
+ `(nnimap ,name
+ (nnimap-address ,address)
+ (nnimap-server-port "imaps")
+ (nnimap-stream ssl)
+ .
+ ,tail))
+ esy-comm-accounts)
+ gnus-no-groups-message "No new articles"
+ gnus-use-full-window nil
+ gnus-article-treat-types '("text/plain"
+ "text/x-verbatim"
+ "text/x-patch"
+ "text/html"
+ "text/calendar")
+ gnus-icalendar-org-capture-file "~/org/inbox.org"
+ gnus-icalendar-org-capture-headline '("Calendar")
+
+ ;; Mastodon
+ mastodon-instance-url "https://emacs.ch"
+ mastodon-active-user "eshel"
+
+ ;; BBDB
+ bbdb-phone-style nil
+ bbdb-complete-mail-allow-cycling t
+ bbdb-completion-display-record nil
+
+ ;; emacsbug.el
+ report-emacs-bug-no-explanations t
+ submit-emacs-patch-display-help nil)
+
+(with-eval-after-load 'gnus
+ (require 'gnus-icalendar)
+ (add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
+ (esy-o365-setup 'gnus)
+ (gnus-icalendar-setup)
+ (gnus-icalendar-org-setup)
+ (bbdb-initialize 'gnus 'mail 'message))
+
+(with-eval-after-load 'message
+ (add-hook 'message-send-hook 'ispell-message))
+
+(with-eval-after-load 'savehist
+ (add-to-list 'savehist-additional-variables
+ 'esy-o365-token-refresh-last-time))
+
+(provide 'esy-comm)
+;;; esy-comm.el ends here
--- /dev/null
+;;; esy-o365.el --- Settings for outlook 365 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2023 Eshel Yaron
+
+;; Author: Eshel Yaron <me@eshelyaron.com>
+;; Keywords: comm
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(defvar esy-o365-token-directory "~/checkouts/M365-IMAP/")
+(defvar esy-o365-token-refresh-last-time 0)
+(defvar esy-o365-token-refresh-command '("python3" "refresh_token.py"))
+
+(defun esy-o365-refresh-token ()
+ (interactive)
+ (files--ensure-directory esy-o365-token-directory)
+ (when-let ((default-directory esy-o365-token-directory)
+ (token (car (process-lines "python3" "refresh_token.py"))))
+ (with-temp-buffer
+ (insert "machine smtp.office365.com smtp-auth xoauth2 login eshel.yaron@student.uva.nl port 587 password \""
+ token
+ "\"\nmachine outlook.office365.com login eshel.yaron@student.uva.nl port imaps password \""
+ token
+ "\"\n")
+ (write-region (point-min) (point-max) ".authinfo"))
+ (auth-source-forget-all-cached)))
+
+(defun esy-o365-maybe-refresh-token ()
+ (let ((now (float-time)))
+ (when (< (* 60 45) (- now esy-o365-token-refresh-last-time))
+ (esy-o365-refresh-token)
+ (setq esy-o365-token-refresh-last-time now))))
+
+;;;###autoload
+(defun esy-o365-setup (mua)
+ (if (not (file-exists-p esy-o365-token-directory))
+ (let ((m "`esy-o365-token-directory' does not exist"))
+ (if after-init-time (user-error m) (display-warning 'comm m)))
+ (require 'auth-source)
+ (add-to-list 'auth-sources
+ (expand-file-name ".authinfo" esy-o365-token-directory))
+ (pcase mua
+ ('gnus
+ (dolist (hook '(gnus-before-startup-hook gnus-before-resume-hook))
+ (add-hook hook #'esy-o365-maybe-refresh-token) )))))
+
+(provide 'esy-o365)
+;;; esy-o365.el ends here