Emacs and w3m: Quick searches

| emacs

A number of browsers allow you to define quick searches so that you can type keywords into your address bar in order to search predetermined sites. With a little bit of code, you can do this in Emacs, too. In this project, you’ll learn how to set up your own keywords to work with w3m and browse-url, so you can use your keywords for browsing both inside and outside Emacs.

First, set up keywords by adding the following lines to your ~/.emacs. We’ll use an associative list of regular expressions and substitutions, like this:

(setq wicked/quick-search-alist
      '(("^g?:? +\\(.*\\)" . ;; Google Web 
         "http://www.google.com/search?q=\\1")
	
        ("^g!:? +\\(.*\\)" . ;; Google Lucky
         "http://www.google.com/search?btnI=I%27m+Feeling+Lucky&q=\\1")
         
	("^dict:? +\\(.*\\)" . ;; Dictionary
	 "http://dictionary.reference.com/search?q=\\1")))

This will turn "g keyword1 keyword2" into a Google search for keyword1 and keyword2.

Next, define advice for the functions that open URLs. Before-type advice allows you to modify arguments before the function is run, and we’ll use that to change the URLs. To modify the URL behavior of w3m, add the following to your ~/.emacs:

(require 'cl-seq)
(defadvice w3m-goto-url (before wicked activate)
  "Use the quick searches defined in `wicked/quick-search-alist'."
  (let* ((my-url (replace-regexp-in-string 
		  "^ *\\| *$" "" 
		  (replace-regexp-in-string "[ \t\n]+" " " (ad-get-arg 0))))
	 (match (assoc-if
		 (lambda (a) (string-match a my-url))
		 wicked/quick-search-alist)))
    (if match
	(ad-set-arg 0 (replace-regexp-in-string
		       (car match) (cdr match) my-url)))))

This sets up your quick searches for use within w3m. To set up quick searches for use with browse-url and external browsers, add the following to your ~/.emacs:

(defadvice browse-url (before wicked activate)
  "Use the quick searches defined in `wicked/quick-search-alist'."
  (let* ((my-url (replace-regexp-in-string 
		  "^ *\\| *$" "" 
		  (replace-regexp-in-string "[ \t\n]+" " " (ad-get-arg 0))))
	 (match (assoc-if
		 (lambda (a) (string-match a my-url))
		 wicked/quick-search-alist)))
    (if match
	(ad-set-arg 0 (replace-regexp-in-string
		       (car match) (cdr match) my-url)))))

To try out your searches, use M-x browse-url RET g emacs RET to do a Google search for all things Emacs, and use M-x w3m-goto-url (usually bound to g) inside w3m to use the quick searches.

You can define more quick searches like this:

(add-to-list 'wicked/quick-search-alist
          '("^ew:? *?\\(.*\\)" . ;; Emacs Wiki Search
            "http://www.emacswiki.org/cgi-bin/wiki?search=\\1"))
You can comment with Disqus or you can e-mail me at sacha@sachachua.com.