在 Emacs 下浏览网页(w3m)和查字典

说起来用 Emacs 浏览网页查字典也不算什么新鲜事了。Emacs 被称为「可编程的编辑器」,功能之强大可以说「只有你想不到没有你做不到」。但那也不是说什么事情 Emacs 都能做的最好。理论上 elisp 作为一种完备的编程语言,你完全可以用它写一个内置的输入法功能和 Fcitx 一样的强大;或者基于语义分析给 Java 弄一个语法检查功能和 eclipse 一样智能。但是那样做的话成本太高了,事实也没有人去做这样的事情:Emacs 内置的输入还是功能简陋到没人用(貌似只能一个字一个字的输入)、用 Emacs 写 Java 还是无比蛋疼。 ** 但是 Emacs 那种把所有工作就集中到一个「终端」上来做的方式有时候确实能节省很多时间。**

比如这里要说的就是用 Emacs 浏览网页和查字典。Emacs 肯定不是最好的浏览器也肯定不是最好的字典软件,但是当我需要在浏览网页的时候查字典,那么用 Emacs 就显现出无比的方便。

先来说说用 Emacs 来浏览网页优缺点。

Emacs 的 w3m mode 是借用 w3m 来浏览网页的,那么缺点非常明显,就是很多网页高级的功能都不支持。如果你用 w3m 来浏览论坛的话你会发现所有的内容都缩成一团了,你要看找到未读的帖子的也会变得很困难。站长精心设计的各种美观的网页效果统统都看不见了。所以说如果上论坛我还是喜欢用 Firefox。(当然这里指的是使用 w3m mode 来浏览网页,其实 Emacs 还可以借用 WebKit 来浏览网页)

但是用 w3m mode 比较适合用来浏览「文字性」的网站、看一些在线文档。比如 openSUSE 的文档和 Emacs 的各种教程,我在 Emacs 上面的网页书签都是这种网站。浏览网页最讨厌的是分心,用 Emacs 的话可以比较好的避免分心,纯键盘操作加上字符界面比较容易让人集中注意力。Emacs 还是可以用来编程(这话说起来有点奇怪,很多人应该主要是用 Emacs 来编程的,虽然我不是)。当我阅读某篇 Common Lisp 的在线教程的时候我可以很方便的把里面的代码复制到 Emacs 里运行。如果你实验的是 Bash 命令,Emacs 还可以保存输出结果到文件里。进一步你可以还在 Eamcs 里发送邮件或者上 IRC 和人家交流。

对我来说比较重要的一点是你可以在 Emacs 里很方便的查询单词。一些在线的字典反应速度太慢了,而本地字典的屏幕取词功能往往不得不动用鼠标「选中」要查询的单词,查完单词又不得不关闭查询窗口。总之非常麻烦。而配上 sdvc 的 Emacs 则非常方便,只要一个快捷键就可以查询光标所在处的单词。


好了,下面进入正题。如何在 Emacs 下浏览网页并查询字典。

要使用 Eamcs 浏览网页的第一步是安装 w3m,在 openSUSE 下非常简单:

sudo zypper in w3m

然后在 Emacs 上安装 w3m mode。Emacs 有自带的「包管理系统」,你可以在 Emacs 下输入 M-x package-install 后回车,再输入要安装的插件名称,这里直接输 w3m 就可以了。安装完了以后我们需要配置一下 w3m mode。打开的配置文件添加你要配置的内容,比如我的是这样的:

(autoload 'w3m "w3m" "interface for w3m on emacs" t)

;; 设置 w3m 主页
(setq w3m-home-page "http://www.google.com")

;; 默认显示图片
(setq w3m-default-display-inline-images t)
(setq w3m-default-toggle-inline-images t)

;; 使用 cookies
(setq w3m-use-cookies t)

;; 设定 w3m 运行的参数,分别为使用 cookie 和使用框架  
(setq w3m-command-arguments '("-cookie" "-F"))

;; 使用 w3m 作为默认浏览器
(setq browse-url-browser-function 'w3m-browse-url)
(setq w3m-view-this-url-new-session-in-background t)


;; 显示图标                                                      
(setq w3m-show-graphic-icons-in-header-line t)
(setq w3m-show-graphic-icons-in-mode-line t)

;; 这行代码是抄了一个比较老的 Emacs 配置的,貌似现在没有什么效果了
;;(setq w3m-view-this-url-new-session-in-background t) 


(add-hook 'w3m-fontify-after-hook 'remove-w3m-output-garbages)
(defun remove-w3m-output-garbages ()
  " 去掉 w3m 输出的垃圾."
  (interactive)
  (let ((buffer-read-only))
        (setf (point) (point-min))
        (while (re-search-forward "\200-\240]" nil t)
          (replace-match " "))
        (set-buffer-multibyte t))
  (set-buffer-modified-p nil))

Emacs 想来因为快捷键众多被人认为难以学习,其实 Emacs 的快捷键是非常有规律的。除了从 Eamcs 快捷键本身的规律性来记忆快捷键以外。也可以通过不同模式提供的功能来分类记忆快捷键。首先我们要明白我们浏览网页需要哪些操作。然后根据操作来记忆。

第一步肯定是打开浏览器。直接 M-x w3m 就可以了。这时 Emacs 会显示你在上面配置文件中所设置的主页。然后呢?当然是打开网页。比较直接的方式当然是输入网址了。直接在 w3m mode 下键入 「U」 就可以了。如果你按下 「U」 的位置正好有个网址,那么默认就会选择打开他,当然你也可以用按 「return」 直接打开它。如果没有网址,那么默认的是你设置的浏览器主页。

用浏览器最常用到的就是搜索引擎了。在 w3m mode 下你可以通过 「S」 以迅速打开搜索引擎进行搜索。默认的搜索引擎是 google,默认搜索的内容是你光标所在处的单词。你也可以自己定制自己的搜索引擎。比如把默认的搜索引擎设置为百度:

(setq w3m-search-default-engine "baidu")

(eval-after-load "w3m-search" '(progn
   (add-to-list 'w3m-search-engine-alist '("baidu"
        "http://www.baidu.com/baidu?wd=%s" utf-8))
   (add-to-list 'w3m-search-engine-alist '("wz"
        "http://zh.wikipedia.org/wiki/Special:Search?search=%s" utf-8))
   (add-to-list 'w3m-search-engine-alist '("q"
        "http://www.google.com/search?hl=en&q=%s+site:stackoverflow.com" utf-8))
   (add-to-list 'w3m-search-engine-alist '("s"
        "http://code.google.com/codesearch?q=%s" utf-8))))    

如果每次打开网页都是输入网址也太麻烦了。虽然我们可以直接打开超链接使用 「return」,但是有时候我们希望保留现在的网页在新的标签也中打开链接,这是有就要使用 w3m-goto-url-new-session,这个函数的默认快捷键需要 「kp-enter」 。这个键指的是在 100% 键盘上数字小键盘上的那个 「enter」 键,可惜很多笔记本没有这个键,我们要另外绑定:

(add-hook 'w3m-mode-hook
                  (lambda ()
                        (define-key w3m-mode-map (kbd "<s-return>") 'w3m-goto-url-new-session)))

顺便提一下当快捷键很多的时候你可以使用另一种比较优雅一点的方法:

;; example of binding keys only when html-mode is active

(defun xah-html-mode-keys ()
  "Modify keymaps used by `html-mode'."
  (local-set-key (kbd "C-c w") 'bold-word)
  (local-set-key (kbd "M-5") 'xhm-wrap-html-tag)

  (local-set-key (kbd "C-c C-p") nil) ; remove a key

  (local-set-key (kbd "<C-right>") 'xhm-skip-tag-forward)
  (local-set-key (kbd "<C-left>") 'xhm-skip-tag-backward)

  )

;; add to html-mode-hook
(add-hook 'html-mode-hook 'xah-html-mode-keys)

;; add to other mode's hook
(add-hook 'nxml-mode-hook 'xah-html-mode-keys)
(add-hook 'xah-html-mode-hook 'xah-html-mode-keys)

这个例子来自 李杀的个人网站 ](http://ergoemacs.org/emacs/emacs_set_keys_for_major_mode.html) 。

当你会打开多个标签以后自然要在标签之间切换咯,这个很简单,就是 C-c C-n 和 C-c C-p。C-c 代表的是某特殊主模式的快捷键,C-n 代表「下一个」,C-p 代表「上一个」。可以根据 Emacs 的快捷键的规律记忆。而同一个标签是前进和后退则使用 「N」 和 「B」,关闭标签的话就使用 C-c C-w。

学会了搜索、打开网页、切换标签以后我们很自然的会想到通过添加书签来快速访问。直接在你要添加书签的网页下按 「a」 就好了。他会提示你输入书签的分类和书签的标题。如果你要把书签添加到已有分类中时可以使用 Eamcs 的自动「补全」功能。如果你想把某个链接添加到书签则要使用 M-a。

访问书签也很容易,按 「v」 就可以了,但是这样会覆盖掉你正在浏览的网页。这时你可能想在新的标签页中打开书签,那么你就要使用 「V」了。

浏览网页以后有时候你可能看到有好东西想要下载。你可以在下载链接处使用 「d」 来下载。如果光标下没有链接,那么就会下载这个网页。使用 M-d 可以选择下载后保存的目录。

好了,记住这些快捷键加上 Emacs 本身就有的移动复制剪切搜索功能你就能很方便的浏览网页了。如果你是网页开发者,再送你两个快捷键好了,一个是 「\」,可以查看网页的源代码;一个是 「=」,可以查看网页的 head。但是我觉得 w3m mode 下查看源代码效果不好,建议保存到文件以后用 web mode 来查看。

你说记不住这些快捷键怎么办,没有关系。当你在 w3m mode 下右击鼠标就会发现有一个菜单出来(如下图)。上面就有你可以采用的操作和对应的快捷键说明。多用几次以后你就可以记住啦。


现在我们要让 Eamcs 可以查阅单词。这里方法有很多,比较原始的是在你的电脑上弄一个字典服务器,然后让 Emacs 去访问。这个实在是太麻烦了。这里使用比较简单的一种 。就是 sdcv。sdcv 是一个命令行字典程序。我们可以在 openSUSE 的教育源里找到,或者使用 一键安装 ](http://software.opensuse.org/package/sdcv?search_term=sdcv) 。

安装好的 sdcv 自身并没有字典。你可以去 这里 ](http://abloz.com/huzheng/stardict-dic/) 下载字典然后解压放在 ~/.stardict/dic 目录下。

然后我们需要让 Emacs 可以使用 sdcv,这样的插件貌似有好几个,这个推荐的是 sdcv-mode.el。这个插件在 Eamcs 的软件仓库里没有,你需要手动下载放到你的 Emacs 可以找到的插件目录里。下载地址在 这里 ](https://code.google.com/p/sdcv-mode/) ()。无法访问的同学可以戳这里 sdcv-mode.txt (7.93 KB)。sdcv 的使用方法很简单:

(require 'sdcv-mode)
(global-set-key (kbd "C-c d") 'sdcv-search)

你可以绑定自己喜欢的快捷键。然后你就可以用 sdcv 在 Emacs 里查字典了,效果就是文章开头的那张图。他会把 Emacs 缓冲区分成两份,看完翻译以后只要按 「q」 就可以关闭显示查询内容的缓冲区啦。

Enjoy!

要我说,这种方法真的挺蛋疼的。。。

为什么呢。。。其实我以前是用 goldendict 的屏幕取词的,也用过 Firefox 的有道插件,还用过 openyoudao。。。经过几次尝试最后发现还是用 Emacs + sdvc 方便。。。。