使用 Emacs 阅读邮件与 RSS
source link: https://liujiacai.net/blog/2021/03/05/emacs-love-mail-feed/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
对于程序员来说,除了编写代码外,阅读邮件与技术文章是耗时比较久的事情,更重要的一点是,这两个的信息输入量都比较大,会涉及到做笔记、TODO 等,一般来说这些事情都是分散在不同应用解决的,但对 Emacs 用户来说,自然希望能在 Emacs 里做所有事。
这篇文章就给读者分享下 Emacs 作为邮件、RSS 客户端的使用方式与心得。在介绍具体配置前,先展示下使用效果(主题使用 gruvbox),以便读者欣赏。
mu4e 主界面
mu4e 邮件列表,默认以话题归类
mu4e 浏览邮件
mu4e 回复邮件
elfeed-dashborad 主界面
elfeed 文章列表
elfeed 浏览文章
阅读邮件我使用的软件主要有
-
offlineimap 使用 imap 协议,以 Maildir 格式来同步邮件;类似的软件有 Mbsync
offlineimap 使用 Python 编写,在 macOS 直接使用 brew 即可安装。下面是我目前的配置文件(配置文件推荐放在 ~/.config/offlineimap/config
,尽量避免直接在家目录创建 ~/.offlineimaprc
)
[general]
# 默认开启的账户,可以是多个
accounts = ljc, outlook
# 定义额外的 python 脚本,里面有获取密码的函数
pythonfile = ~/.config/offlineimap/pass.py
# 开始配置第一个账户
[Account ljc]
# 一个账户主要包含 local 与 remote 这两个配置项
localrepository = LocalLJC
remoterepository = RemoteLJC
# 可选配置项,邮件同步时间:这里只同步 365 天之内的
# 需要注意,一些邮件提供商也存在同步限制,比如 QQ 邮箱默认只同步 30 天内的数据,可以在设置中修改
maxage = 365
[Repository LocalLJC]
type = Maildir
localfolders = ~/.mail/ljc
# 需要与 RemoteLJC 里面的 nametrans 配置起来使用,解释见正文
nametrans = lambda folder: re.sub('^=', '&UXZO1mWHTvZZOQ-/', folder)
[Repository RemoteLJC]
nametrans = lambda folder: re.sub('^&UXZO1mWHTvZZOQ-\/', '=', folder)
# 配置 ssl 证书,macOS 下安装 openssl 即可
sslcacertfile = /usr/local/etc/[email protected]/cert.pem
# 过滤掉一些目录,不进行同步
folderfilter = lambda f: 'kK5O9l9SaGM' not in f and '&UXZO1mWHTvZZOQ-' != f
# 下面是 IMAP 的配置,我这里是使用的腾讯企业邮箱
type = IMAP
remotehost = imap.exmail.qq.com
remoteport = 993
remoteuser = [email protected]
# 调用 pass.py 中的函数获取密码
remotepasseval = get_password_emacs("imap.exmail.qq.com", "[email protected]", "993")
# 也可通过下面配置直接设置密码
# remotepass = YOUR_MAIL_PASSWORD
[Account outlook]
... 大致同上,这里不在赘述
上面的配置比较直观,也有相应注释,这里重点介绍如何设置 remotepasseval
与 nametrans
。
GPG Auth Source 配置密码
Emacs 中使用 Auth Source 来管理密码,它相当于一个接口层,可以对接多个存储后端,netrc 是最常见的后端,除此之外,还支持 JSON、Secret Service API、pass。很多命令,比如 wget、curl、git 等都支持从 netrc 读取密码,因为这里只介绍其用法:
machine mymachine login myloginname password mypassword port myport
上面描述了 netrc 文件的通用格式,下面是我邮箱的相关配置:
# cat ~/.authinfo machine imap.exmail.qq.com login [email protected] password 123456 port 993 machine smtp.exmail.qq.com login [email protected] password 123456 port 465
993 是 imap 端口,接受邮件用;465 是 smtp 端口,发送邮件用。为了安全,还可以对 netrc 使用 GPG 加密,Emacs 会自动解密读取。
(setq auth-sources '("~/.authinfo.gpg" "~/.authinfo" "~/.netrc"))
Emacs 默认从上面几个地方找文件,读者可按需修改。
我上面对配置中使用了 get_password_emacs 这个函数来获取密码,其实现如下:
def get_password_emacs(machine, login, port):
s = "machine %s login %s password ([^ ]*) port %s\n" % (
machine, login, port)
p = re.compile(s)
authinfo = os.popen("gpg -q --no-tty -d ~/.config/authinfo.gpg").read()
return p.search(authinfo).group(1)
nametrans 文件名转换
配置好密码后,就可以进行邮件同步了。但是在同步前,可以通过 offlineimap --info
命令查看邮件服务器中的内容,确认下需要同步哪些目录
$ offlineimap --info
OfflineIMAP 7.3.3
Licensed under the GNU GPL v2 or any later version (with an OpenSSL exception)
imaplib2 v2.101 (bundled), Python v2.7.17, OpenSSL 1.1.1i 8 Dec 2020
imaplib2: 2.101 (bundled)
Remote repository 'RemoteLJC': type 'IMAP'
Host: imap.exmail.qq.com Port: None SSL: True
Establishing connection to imap.exmail.qq.com:993 (RemoteLJC)
Server supports ID extension.
Server welcome string: * OK [CAPABILITY IMAP4 IMAP4rev1 ID AUTH=PLAIN AUTH=LOGIN NAMESPACE] QQMail IMAP4Server ready
Server capabilities: ('IMAP4', 'IMAP4REV1', 'XLIST', 'MOVE', 'IDLE', 'XAPPLEPUSHSERVICE', 'NAMESPACE', 'CHILDREN', 'ID', 'UIDPLUS')
folderfilter= lambda f: 'kK5O9l9SaGM' not in f and '&UXZO1mWHTvZZOQ-' != f
nametrans= lambda folder: re.sub('^&UXZO1mWHTvZZOQ-\/', '=', folder)
Folderlist:
&UXZO1mWHTvZZOQ- (disabled)
&UXZO1mWHTvZZOQ-/clojure -> =clojure
&UXZO1mWHTvZZOQ-/GitHub -> =GitHub
&UXZO1mWHTvZZOQ-/golang -> =golang
Deleted Messages
Drafts
INBOX
Junk
Sent Messages
在 Folderlist 下面就是邮件服务器中的目录, &UXZO1mWHTvZZOQ-
开头的目录为自定义目录,为了保证同步下来的目录中没有这一串字母,我使用 nametrans
配置把它转化为了 =
符号。
由于 IMAP 的同步是双向的,本地的状态也需要返回给远端,因此在 LocalLJC 中又使用 nametrans
把 =
转成了那串字母,这样两边就能正确同步邮件状态了,下面是本地的状态:
Local repository 'LocalLJC': type 'Maildir'
nametrans= lambda folder: re.sub('^=', '&UXZO1mWHTvZZOQ-/', folder)
Folderlist:
INBOX
Drafts
Junk
=GitHub -> &UXZO1mWHTvZZOQ-/GitHub
Deleted Messages
=golang -> &UXZO1mWHTvZZOQ-/golang
=clojure -> &UXZO1mWHTvZZOQ-/clojure
Sent Messages
最后,直接运行 offlineimap
就可以同步邮件了。
邮件同步到本地后,在使用前需要使用 mu 建索引,参考命令:
export XAPIAN_CJK_NGRAM=true
# 只需要执行一次 init,可以指定多个邮件地址
mu init --my-address [email protected] --my-address [email protected] -m ~/.mail
# index 在每次收取邮件后都需要执行,mu4e 可以配置自动执行
mu index
XAPIAN_CJK_NGRAM
环境变量主要是开启对 CJK 的分词,方便用中文搜索邮件。不过 mu 使用的 Xapian 对中文支持比较弱,只能搜索两个字的词,比如搜「雷峰塔」就不行,可参考这里的解决方案。
mu4e 在 mu 的安装目录内,不需要再额外安装。除 mu4e 外,推荐安装下面这几个 Emacs 插件
-
maildirs,它可以把每个目录邮件数展示出来。mu4e 相关配置可以在
-
org-mime,它可以把 org-mode 格式转为 HTML 的邮件
-
visual-fill-column,相当于 fill-column 与 visual-line-mode 的结合版,主要方便在大屏显示器上阅读,效果是把长行拆分是多行。
这几个插件的配置可以在这里找到,这里主要介绍核心配置,细节不再赘述:
-
mu4e-contexts
配置多账户 -
mu4e-update-interval
配置自动同步邮件与建索引间隔 -
mu4e-get-mail-command
配置同步邮件的命令 -
mu4e-view-actions
增加mu4e-action-view-in-browser
,这样在阅读邮件时,按a b
在浏览器打开邮件,这对那些只有 HTML 格式的邮件来说比较重要 -
message-citation-line-format
定义符合 Gmail 的引用格式,Gmail 会用...
将引用隐藏起来 -
mu4e-maildirs-extension-custom-list
配置目录展示顺序 -
org-mime 主要有两种使用方式
-
在一个 org 文件中调用
org-mime-org-buffer-htmlize
(推荐绑定到C-c C-c
),这会自动把当前 org 文件转为 html 并打开编辑邮件的 buffer -
在编辑邮件的 buffer 中,调用
org-mime-edit-mail-in-org-mode
(推荐绑定到C-c '
)打开 org-mode 编辑区,编辑好后调用org-mime-htmlize
(推荐放到message-send-hook
里面)将 org 格式转为 html 邮件
-
配置好后,直接运行 M-x mu4e
就能打开主视图 mu4e-main-view
,通过快捷键来在不同视图下切换(图片来源):
mu4e 主要视图交互流程
下面是我在不同视图下,常用的一些快捷键:
-
j
跳转目录 -
b
跳转书签 -
U
收取邮件与重建索引
-
g
访问当前邮件中的 URL -
a
Action 选项 -
h
html/text 格式切换 -
.
查看邮件源文件 -
A
附件选项 -
C
写新邮件 -
R
回复邮件
compose
-
C-c C-c
发送 -
C-c C-k
废弃 -
C-c C-d
存草稿 -
C-c C-a
添加附件
Flags 含义
查询语法
date:today..now
今天的邮件
from:jim and not flag:attach
来自 jim 且没有附件的邮件
"maildir:/Sent Items" and rupert
发送目录内,包含 rupert 的邮件
subject:wombat and date:20170601..20170630
指定时间内,主题中包含 wombat 的邮件
说明:mu 使用 https://emacs-china.org/t/topic/305/77?u=jiacai2050
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK