Emacs ですぐに単語の検索をしたい欲望を叶える Elisp。

Emacs で何か作業しているときに、検索したいというのはよくある話です。
そこで、Google だったり、辞書だったり、AMAZON だったりを開いて検索するわけですが、幾度も繰り返す行為なので、一発で Emacs 上から検索したいと思いました。
そこで、

  1. カーソルのある単語か、リージョンを
  2. コマンド一発で任意の検索エンジンの結果を開く

という Elisp を作ればいいやんということを考えついたので、とりあえず形にしてみました。

本体は、とりあえず以下のような感じ。

(defvar search-engines
  '(("s" . "http://reference.sitepoint.com/search?q=%s")
	("g" . "http://www.google.com/search?q=%s")
	("gj" . "http://www.google.com/search?hl=ja&q=%s")
	("ge" . "http://www.google.com/search?hl=en&q=%s")
	("m" . "http://maps.google.co.jp/maps?hl=ja&q=%s")
	("y" . "http://search.yahoo.co.jp/search?p=%s")
	("yt" . "http://www.youtube.com/results?search_type=&search_query=%s&aq=f")
	("tw" . "http://search.twitter.com/search?q=%s")
	("goo" . "http://dictionary.goo.ne.jp/srch/all/%s/m0u/")
	("a" . "http://www.answers.com/topic/%s")
	("ew" . "http://www.google.com/cse?cx=004774160799092323420%%3A6-ff2s0o6yi&q=%s&sa=Search")
	("eow" . "http://eow.alc.co.jp/%s/UTF-8/")
	("z" . "http://www.amazon.com/s/url=search-alias%%3Daps&field-keywords=%s")
	("zj" . "http://www.amazon.co.jp/gp/search?index=blended&field-keywords=%s")
	("y" . "http://search.yahoo.com/search?p=%s")
	("yj" . "http://search.yahoo.co.jp/search?p=%s")
	("we" . "http://www.wikipedia.org/search-redirect.php?search=%s&language=en")
	("wj" . "http://www.wikipedia.org/search-redirect.php?search=%s&language=ja"))
  "A list is search engines list. keys engines nick, and value is search engine query.
Search word %s. In formatting url-hexify. Use %% to put a single % into output.")

(defun search-web (engine word)
  (browse-url
   (format (cdr (assoc engine search-engines)) (url-hexify-string word))))

(defun search-web-at-point (engine)
  "search web search engine for word on cursor.
arg is search-engines keys."
  (interactive "sSearch engine: ")
  (search-web engine (substring-no-properties (thing-at-point 'word))))

(defun search-web-region (engine)
  (interactive "sSearch engine: ")
  (let ((beg (mark))
        (end (point)))
	(search-web engine (buffer-substring-no-properties beg end))))

http://github.com/tomoya/search-web.el/raw/master/search-web.el
から最新のものを入手して、(require 'search-web) すればとりあえず関数が使えるようになります。
また、併せて以下の設定を .emacs に書けばキーバインド一発で色々な検索ができます。

;; google
(define-key global-map (kbd "C-c C-s g") (lambda () (interactive) (search-web-at-point "g")))
(define-key global-map (kbd "C-c C-s C-g") (lambda () (interactive) (search-web-region "g")))
;; 英辞郎
(define-key global-map (kbd "C-c C-s e") (lambda () (interactive) (search-web-at-point "eow")))
(define-key global-map (kbd "C-c C-s C-e") (lambda () (interactive) (search-web-region "eow")))
;; AMAZON
(define-key global-map (kbd "C-c C-s z") (lambda () (interactive) (search-web-at-point "zj")))
(define-key global-map (kbd "C-c C-s C-z") (lambda () (interactive) (search-web-region "zj")))
;; Yahoo! JAPAN
(define-key global-map (kbd "C-c C-s y") (lambda () (interactive) (search-web-at-point "yj")))
(define-key global-map (kbd "C-c C-s C-y") (lambda () (interactive) (search-web-region "yj")))

search-at-point が、カーソルのある付近の単語を検索する関数。search-web-region が、リージョンを検索する関数になっています。
任意の検索エンジンを追加したければ、

(add-to-list 'search-engines '("d" . "dict:///%s"))

という風にリストに追加します。もしくは、setq で上書きして下さい。
すると、

;; Mac の辞書
(define-key global-map (kbd "C-c C-s d") (lambda () (interactive) (search-web-at-point "d")))
(define-key global-map (kbd "C-c C-s C-d") (lambda () (interactive) (search-web-region "d")))

Mac 標準の辞書でも調べることができます。
これは、えりむんのアイデアgist: 129266 - GitHubがとても参考になっております。

改善案

現在、search-web-at-point or region を呼び出すと、検索エンジンを聞いてくるが、これをリストのキーから補完したい。
org-mode のタグ補完みたいな感じで、ワンキー + エンタで検索エンジンをチョイスするのが利用的か。
これだと、コマンドを幾つも追加しなくても、ひとつのコマンド+エンジン選択+エンタで検索できて便利じゃないかな?という感じ。
まぁ、しかし方法が分かんないので、また調べて分かれば改善していきたいと思います。