|
|
用户名:JustinLei 笔名:JustinLei 地区: 常州 行业:其他 |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
VIM
Thread类和Runnable接口
让Ubuntu默认显示MAC风格的圆体字体
让kpdf支持中文
Debian输入法 SCIM 配置文件
Make File
Emacs基本命令(移动)
用gnus 收发邮件、泡新闻组
启动 gnus 非常简单,在你的 Emacs 里执行 M-x gnus 命令就可以了,如果你想在另一个 frame 里启动 gnus,那就执行 M-x gnus-other-frame 。但是,现在先别启动,因为我们先得进行一些配置。 gnus 启动的时候会去读你写在 ~/.gnus.el 里的内容,就像 Emacs 启动时要读 ~/.emacs 一样。当然你也可以把对 gnus 的配置写在 ~/.emacs 里,但是最好还是使用 gnus 自己的配置文件。
首先,我们要设置新闻服务器,也就是 nntp 服务器, nntp 是 Network News Transfer Protocal 的缩写,国内提供 nntp 服务的主机不多,教育网内能访问的nntp 服务器,我只找到了一个: news.cn99.com,好了,现在就在 ~/.gnus.el 里加上这一句:
现在,我们进行接收邮件的设置。玩*nix 的老鸟都知道,*nix 的哲学是每个程序"Only do one thing, and do it well." 因此就有了 sendmail, fetchmail, mailreader 等等一大票程序来干收发邮件这个活儿。严格地说 Emacs(gnus) 的分工是做 mailreader,也就是说我们用 emacs 来写信,然后由另一个程序,比如sendmail 来把信发出去;收信的过程也是类似的,由一个程序(比如 fetchmail) 负责把信取回来,放在一个 spool 里面,然后我们用 Emacs 来读信。你先别跑,我不是让你去配置 sendmail 这样的大怪物,我们平常发发信、收收信这点小活儿,用不着劳 sendmail 老人家的大驾。
我们用的最多的邮件收发方式是这样的,有个 POP3 服务器,收信时我们到那里去取;有个 SMTP 服务器,发信时我们把信送到那里去。这点小活儿,现在 emacs 自己就可以搞定了。现在我们看看怎么设置:
首先我们设置 POP3 服务器:
然后我们还要告诉 gnus 如何存放接收来的邮件, gnus 把这个叫做 backend,最常用的方式是 nnfolder,另外还有 nnmbox, nnml 等其它几种方式,我们选择其中一种就可以了:
然后我们设置 SMTP 服务器,采用 smtp 方式发送邮件需要一个小程序 smtpmail.el, 这个程序现在已被纳入了官方的 Emacs,如果你用的是最新的 CVS Emacs,比如 Emacs22, Emacs23 等,就已经包含了这个程序。你可以检查一下 emacs 的安装目录中 lisp/mail/ 目录下有没有这个文件,如果没有的话,就只好自己下载、安装了。现在我们看看如何设置:
中文!中文!永远都是头痛的事儿。把下面这些加在 .gnus.el 里面吧:
另外,有些用 web 方式发出的邮件里有 html,加入下面的设置,只看其中的plain text 部分:
现在我们可以选择几个自己喜欢的新闻组,作为默认的新闻组:
现在到了关键时刻,成败在此一举:
M-x gnus
嘿嘿,傻眼了吧, Emacs 没反应了!!! 没关系,表担心,这是正常现象, gnus 是个单线程程序, nntp 服务器又慢的要命(你要是在公网,说不定能好点儿),多等一会儿就好了,一般也就两三分钟,运气不好的话还要长些,什么?你等不及了,要编辑文件?那就只好麻烦您老再开一个 Emacs 吧!
如果一切正常, gnus 启动完成的时候,我们就会看到 group buffer,这里列出了我们订阅的新闻组,类似这样:
新闻组前面的数字,表示这个组里还有多少帖子没读过。现在,只要把光标移动到要读的新闻组上面,敲下回车键就可以读帖子了。
不要 kill 掉这个 buffer 哟,我们经常需要回到这个 buffer 。如果你读完了新闻、信件,想退出 gnus,只要在这个 buffer 里按下 q 键就可以了。
当我们阅读某个新闻组的时候,就会进入 summary buffer,其中列出了作者和帖子的标题,如果是跟帖,会缩进表示,象下面这样:
如果要读贴子,只要按下空格键就行了。按下 q 键将返回到 Group buffer.
在 newsgroup 里发帖子叫 post article, 发贴子很简单,只要我们按下 a 这一个键就可以了,写完后 C-c C-c 发出,如果写了一半儿想取消,则键入 C-c C-k 。
在 newsgroup 回帖子叫 follow up,按下 f 键就行了,但是这样回帖并不引用原作者的文章,如果你想引用原作者的文章,那就用 F 键。
如果你想和文章的作者私下聊聊,那就用 r 或者 R 键,给原作者回信叫做reply to, 这时只有原作者一个人能收到信,与 follow up 不同, follow up 的时候,凡是订阅了新闻组的人都能读到信。
按照手册中的说法,我们通过 POP3 接收到的信件会被送到一个叫做 mail.misc 的组里, gnus 会自己建立这个组,但是我找了好几天也没找到。怎么办?没关系,我们自己建一个:
在 Group buffer 里,键入 G m,系统提示我们输入组名: mail.misc,然后提示我们输入 server 名,此时我们输入: nnfolder,注意,服务器名要与你选择的 backend 一致。
建立完成之后,我们可以在 Group buffer 里键入 ^,此时我们将进入 Server buffer, 在这里我们将看到自己选择的服务器,比如: news.cn99.com 。其中, nnfolder 服务器里应该有我们新建的 mail.misc 组。我们在服务器名上输入回车,这样就能看到这个服务器中的组,在想要订阅的组上面按下'u'键即可订阅这个组,取消订阅同样也是用这个键。
用 gnus 发信极其简单,随时都可以,按 m 一键搞定, gnus 会新建一个buffer 让我们写信
写完信后 C-c C-c 发出, 不想要了就 C-c C-k 。
现在我们已经完成基本任务了,但是大功告成了吗? 没有!苦难才刚刚开始...... 我看到一篇很好的帖子,怎么才能保存下来? 我想备份自己发出的所有信件,怎么办? 我想删除信箱里的信件,怎么办? 我的联系人很多,我想建个地址簿,怎么办? 我想把不同的人发来的信,分别放在不同的信箱里,怎么办?
你可能已经注意到了,当你读过一个帖子之后, Gnus 会自动在帖子的最左边加上一个 R ,这就是标记。这些标记有些是我们自己加上的,有些是 Gnus 自动加上的。标记不止 R 一个,还有很多符号被 Gnus 用来当作标记符号。这些标记表明了帖子的状态,比如 R 表示这个帖子你已经读过了。
现在我们来看看常见的标记是什么意思。标记分为两大类,一类是“已读(read)”标记,一般用字母表示,比如 R, r, O, E 等等;另一类是“未读(unread)”标记,一般用特殊符号表示,比如 !, ?, *等等。标记的数量比较多,但我们只要了解常见的几个标记是什么意思就行了。
Gnus 之所以要把帖子分为“已读”和“未读”两类,是因为对这两类帖子,Gnus 采取的处理方式不同。如果一个帖子别标记为“已读”,那么当你离开这个group(用 q 命令)以后,下次再进入的时候,你就不会再见到它了(除非你要求gnus 把老帖翻出来给你看),只有那些被标记为“未读”的帖子和新帖才会显示给你看。
用 M c 或者 Meta-u 清除所有标记,也就是说标记为“未读(unread)”。
要想永久保存有价值的帖子,也就是说把帖子拷贝到自己的机器上保存起来,那么可以打开 gnus 的 cache 功能,在 .gnus.el 中加入:
以后看到有价值的帖子,只要按下 * 键,这篇帖子就会被拷贝到本地的 cache 中保存起来,这样即使服务器那边删除了这篇帖子,也没关系了。如果你又不想要了,用 Meta-* 就可以把帖子从缓存中删掉。
如果你想查看自己保存在缓存里的帖子,只要在 summary buffer 中用 'Y c' 命令即可。
可能你每天都要收到大量的邮件,有的是亲朋好友寄来的,有的是你订阅的maillist 寄来的。如果这些邮件都放在 mail.misc 这一个组里,那么很快这里就会拥挤不堪了,说不定有些重要的信件会被漏看。
在 Gnus 里,我们可以对收到的邮件进行分类,比如把所有来自 tsinghua.edu.cn 的信都放在mail.tsinghua 这个组里。我们可以这样做:
首先我们建一个 mail.tsinghua 组,在 Group buffer 里键入 G m , 然后输入 "mail.tsinghua", 接着系统会让我们选择 Method,此时输入"nnfolder",这样 mail.tsinghua 这个组就建立好了。
然后我们设置 nnmail-split-methods 变量,在 .gnus.el 中加入:
这样以后凡是来自 tsinghua.edu.cn 的信件都会被放到 mail.tsinghua 这个组里去。这个变量的值是一个由 list 组成的 list,每个 list 由两个部分组成,前面的是组名,比如"mail.tsinghua", 后面的是个正则表达式, Gnus 会按这个正则表达式的要求到邮件里去搜索,然后把找到的邮件放在指定的组里面。
这是一种简单的分类方式,如果你觉得不过瘾,可以试试 nnmail-split-fancy,那是一种更灵活的分类方式。
需要注意的一点是,我们刚才用的术语都是“组(group)”,而没有说“邮件夹”。实际上,在 Gnus 里面组就是邮件夹,邮件夹就是组,我们说过, Gnus 采用同样的方式处理信件和新闻,因此它并不对组和邮件夹进行区分。
既然是 group,那么你就可以取消订阅,假如你把女朋友的来信都放在mail.lovers 组里面,随后不小心 unsubscribe 了这个组,那么你就读不到她们的来信了,要是你的女朋友跟你分了手,千万别怪 Gnus,就像 Gnus 的手册里说的:
Gnus gives you all the opportunity you could possibly want for shooting yourself in the foot.
基本上所有的邮件客户端都有一个“已发送邮件”或是“ sent ”的邮件夹,你自己写的信发送出去的同时,都会在这里都有一个备份,因为我们有时候需要看看自己发出去的信件。
在 Gnus 里做到这一点很容易,而且它还可以自动把你发出去的邮件分分类,比如把发出去的信放在一个组里,把你在 newsgroup 里 post 的帖子放在另一个组里。
现在我们看看怎么做到这一点,比如我们想把自己发的信备份到 mail.sent.mail 组里,把自己 post 的帖子备份到在 mail.sent.news 组里,那么首先我们建立这两个组:
在 group buffer 里键入 G m ,然后输入组名"mail.sent.mail", 接着是输入 "nnfolder", 这个组就建好了,然后用同样的方式建立"mail.sent.news"组。
最后在.gnus.el 里加入:
当你想删除一个邮件的时候,你先得搞清楚它是个 news 还是个 mail, 因为你是没有权力删除新闻组里的文章的,就象你上 BBS 的时候一样,就算你看到一篇不爽的帖子,你也删不了它,除非你是版主。
在这里我还要多一句嘴, newsgroup 管理的不像 bbs 那样严格, bbs 的每个版都有若干版主进行管理,删除无关的文章,封禁不按规矩发帖的人等等,象 joke 这种大板,有8个版主严阵以待,随时准备删贴封人。 newsgroup 是没有版主管理的,一般只有 nntp 服务器的管理员才有删帖的权力,但是一个 nntp 服务器上有成千上万的 group,管理员才没时间管删帖这种事儿呢,他们一般是制定一些规则,让系统自动删除一些过期的帖子。因此,如果你在 newsgroup 上发了个垃圾帖子,它就有可能在那里呆上好几年。
正因为如此,我们在 newsgroup 上发帖子一定要慎重,不要发垃圾邮件什么的。更严重的是,如果你发了这种邮件,那么订阅这个组的人就会认为你很不礼貌,不懂规矩,他们可能就会在自己的 Gnus 里增加一条规则,从此以后凡是你发表的帖子,他们都不下载、不看。
好了,言归正传,我们谈谈怎么删除邮件。有两种方法可以删除邮件,一种是使用邮件专用命令` B DEL', 也就是现键入'B',然后再按'Delete'键,这时系统会询问你是否真的要删除什么的,回答 yes 就可以了。但是这种方法太暴力了,在Gnus 里有一种更好的方法删除邮件,那就是给邮件加上“保质期”,也就是说,让Gnus 替你干删除邮件这个活儿,它会忠实地按照你的要求,删除“过了保质期”的邮件。
怎样给邮件加上“保质期”呢,很简单,在邮件组的 summary buffer 里,用 E 键就可以给光标所在的邮件贴上 expirable 的标签,此时帖子前面会出现一个字母 E 作为标记,然后你就不用管了,到了期限, gnus 就会自动删除它们。
你也可以用 E 命令,给新闻组里的帖子加上 expirable 的标签,但是这毫无意义,因为不论是你还是 Gnus 都无权删除新闻组里的帖子。
Gnus 默认的保质期是7天,如果你觉得时间不合适,可以自己设置,更改变量
nnmail-expiry-wait 的值就行了,在 .gnus.el 里加入:
你还可以给不同的组设置不同的保质期,象下面这样:
这样就把 mail.tsinghua 这个组的保质期设为31天, mail.misc 组设为3天等等。除了数字,还有另外两个符号可以用,一个是 immediate ,表示立即删除标为过期的邮件;另一个是 never ,表示永不删除过期的邮件,“如果你一定要加个期限, Gnus 希望是一万年。”
如果你的联系人比较多,没办法全部记住这些人的 email 地址,想建个地址簿,该怎么办呢?
有两个种方法可以完成这个任务,一种是简单的,但是不太灵活;另一种麻点儿,但是功能很强。
先说简单的,实际上这是一种很古老的方法了,那就是采用 mail alias (地址别名),你只要把联系人的邮件地址和别名都写在 ~/.mailrc 文件里就行了,语法很简单,每个联系人占一行,像下面这样:
发信的时候,在 To: 后面输入别名,比如 heyyy,然后按空格键, Gnus 会自动把全名替你插进去。
然后我们再说复杂点儿的,其实也不复杂,只是麻烦点儿,要自己去下载一个软件包,到这里:
http://bbdb.sourceforge.net/
去下载一个叫做 bbdb 的软件包,全名是 "Insidious Big Brother Database"。不知怎么搞的,现在一提数据库我就开始反胃,不过这个 bbdb 只是个 Emacs 扩展,全都是用 elisp 写成的,并不是那种巨无霸似的操作繁琐的数据库管理系统。bbdb 很小,压缩包只有300多 k 。 bbdb 只是建立了一个~/.bbdb 文件,然后把你的联系人每个一行地写在里面罢了,这是个纯文本文件,不过最好不要自己编辑这个文件,可以用 bbdb 的命令往里添加联系人。
下载回来以后解开,然后 make 一下,象这样:
然后把 bbdb-2.35 目录下的 lisp 子目录整个扔到 site-lisp 下面就行了:
还有文档,如果你要看的话也要自己装:
如果你觉得太麻烦了,也可以解开压缩包后,直接把 lisp/ 子目录整个扔到 site-lisp 下面, bbdb 的手册中说可以这样,不过我没试过。
好了,把下面这些写在 .gnus.el 里面:
然后重新启动 Gnus, 或者是在 Group buffer 中用 r 键,让 Gnus 重新读入~/.gnus.el
bbdb 使用起来很简单,第一次用的时候,要用"M-x bbdb-create"命令创建联系人,此时 bbdb 会问你一些相关的问题,比如联系人的 Name, company, Network Address(这里要添 email 地址)等等,你如实回答就是了。然后 bbdb 会创建一个~/.bbdb 文件,并把你的联系人加进去。
以后你可以随时用"M-x bbdb-create"命令添加联系人,也可以用 `M-x bbdb RET RET' 命令让 bbdb 把所有联系人显示给你看。
不过, bbdb 最方便的地方在于你写信的时候,只要在 To: 面用 TAB 键, bbdb 就会把联系人替你填好,如果不对,就继续按 TAB 键, bbdb 会填下一个,循环往复。
还有一个方便的地方,如果你在 Summary buffer 中的某个邮件或帖子上按 : 建, bbdb 将自动把发信人替你加到地址簿里,方便吧!
说了这么多,也只是把Gnus最基本的功能介绍了一下,实际上,Gnus还有很多高级的功能可以发掘。那就去读 Gnus 的 manual 吧,我觉得 Gnus 的手册写的真不错,语言诙谐幽默,读起来趣味盎然。
当你用了一段时间 Gnus 以后,你就很难再离开它了,那时候你就会理解下面这句话:
No Gnus is bad news.
Eclipse家族法则(促成者)
促成者:
1.邀请法则(Invitation Rule):尽可能的邀请别人为你的作品做出贡献
2.懒加载法则(Lazy Loading Rule):只有在真正需要的时候才加载插件
3.安全平台法则(Safe Platform Rule):作为扩展点的提供者,你必须保护好自己,不要让扩展者的误操作给你造成损失
4.公平竞赛法则(Fair Play Rule):所有使用者遵守同样的游戏规则,包括我自己
5.明确扩展法则(Explicit Extension Rule):明确说明平台的什么地方可供扩展
6.发散性法则(Diversity Rule):一个扩展点接纳多个扩展
7.良好防御法则(Good Fences Rule):如果要交出程序的控制权,首先保护好你自己
8.用户决定法则(User Arbitration Rule):如果有多个选择,由用户决定使用哪个
9.明确API法则(Explicit API Rule):将API与插件内部使用的类分开
10.稳定性法则(Stability Rule):如果你已经开始邀请其他人作出贡献,就不要再改变规则
11.保守API法则(Defensive API Rule):只暴露你有信心的API,但同时也要做好准备暴露更多的API,因为使用者会邀请你这样做
传递和返回对象:传递句柄
将句柄传递进入一个方法时,指向的仍然是相同的对象。
public class PassHandles {
static void f(PassHandles h) {
System.out.println("h inside f(): " + h);
}
public static void main(String[] args) {
PassHandles p = new PassHandles();
System.out.println("p inside main(): " + p);
f(p);
}
}
toString 方法会在打印语句里自动调用,而PassHandles 直接从Object 继承,没有toString 的重新定义。
因此,这里会采用toString 的Object 版本,打印出对象的类,接着是那个对象所在的位置(不是句柄,而
是对象的实际存储位置)。输出结果如下:
p inside main(): PassHandles@1653748
h inside f() : PassHandles@1653748
可以看到,无论p 还是h 引用的都是同一个对象。这比复制一个新的PassHandles 对象有效多了,使我们能
将一个参数发给一个方法。但这样做也带来了另一个重要的问题:别名问题