Reader mode

Many browsers now have some form of mode that tries strips a web page of all frills and leave just text displaying, so you don’t see headers, menus, sidebars, ads, etc. just core page content in a way that’s easy to read.

Emacs-w3m can do this with page filters. See WThreeMFilters.

Open a url embedded in any buffer

BrowseUrl is a package bundled by default in the emacs distribution that allows one to select a URL in any emacs buffer and open that URL in a browser of your choice. By default, it is bound to `C-x m`. In order to select emacs-w3m as the browser for it to open:

 (setq browse-url-browser-function  'w3m-goto-url-new-session)

View a file from within Dired

‘M-x browse-url-of-dired-file’

View the current buffer as rendered HTML

‘M-x browse-url-of-buffer’ , bound by default to `C-c C-v` in html-mode.

Downloading files asynchronously

emacs-w3m performs downloads asynchronously, so you can continue working while something is being downloaded. Should you wish to abort a download, press ‘C-c C-k’.

Saving buffers for future emacs sessions

emacs-w3m has an extensive ability to save its buffers for future use, for example in future emacs sessions. Note that the nomenclature can be slightly confusing because each collection of emacs-w3m buffers is called a session.

By default, emacs-w3m automatically keeps track of the open buffers and maintains a “crash recovery session”, “automatic saved session” and possibly any number of “removed sessions”, so even if you haven’t manually saved anything, you probably have the ability to recover past work. Type ‘M-s’ to see a pop-up window listing the current collection of saved sessions. On any line, the number in brackets is the number of buffers saved for that entry. You can delete entries using the ‘d’ command, and restore an entire session by pressing ‘return’ on an entry. ‘q’ exits the window.

But there’s more. You can examine the details of any entry by pressing ‘M-s’ on it. Then, you can use the ‘d’ command to selectively delete its entries, or you can selectively restore single entries by pressing ‘return’ on them.

At any time while using emacs-w3m, you can save your session by pressing ‘M-S’ (capital S for saving a session; lower-case s for viewing the list).

Using TextMode for textareas

(by DavidEdmondson)

The default mode for editing textareas is somewhat annoying - I’d much rather use TextMode. Here’s a small addition to your .emacs to make that possible:

 (eval-after-load "w3m-form"
     (define-minor-mode dme:w3m-textarea-mode
       "Minor mode used when editing w3m textareas."
       nil " dme:w3m-textarea" w3m-form-input-textarea-keymap)
     (defun dme:w3m-textarea-hook ()
       ; protect the form local variables from being killed by `text-mode'
       (mapcar (lambda (v)
		 (if (string-match "^w3m-form-input-textarea.*"
				   (symbol-name (car v)))
		     (put (car v) 'permanent-local t)))
     (add-hook 'w3m-form-input-textarea-mode-hook 'dme:w3m-textarea-hook)))

I just simply use this as my w3m-form-input-textarea-mode-hook:

 (defun dka-w3m-textarea-hook()
    (while (re-search-forward "\r\n" nil t)
      (replace-match "\n" nil nil))

After you quit the buffer, it restores your window config nicely. 😊 In other words, the patch previously posted here isn’t really needed.

Saving a link's target

There used to be a definition for a nice little function here to save the target of link under the point to the kill-buffer, and also to the clipboard for yanking (pasting) to other programs, f.ex. This feature is implemented in the WThreeM itself, however, so the little defun can go. That function is w3m-print-this-url, by default bound to u. There is also the w3m-print-current-url (at c), which copies the current URI of the page currently being viewed.

Copying URL at point

I like the “Copy link target” function of firefox so I wrote this function so that I don’t have to go to the page pointed to by the link, hit U C-a C-k C-g B to get the actual value of the link under the point. Also included code to set it as Alt-W locally in the w3m buffer using the w3m-mode-hook.

  (defun w3m-copy-url-at-point ()
    (let ((url (w3m-anchor)))
      (if (w3m-url-valid url)
  	  (kill-new (w3m-anchor))
        (message "No URL at point!"))))
   (add-hook 'w3m-mode-hook
	  (lambda ()
	    (local-set-key "\M-W" 'w3m-copy-url-at-point)))

Isn’t this what w3m-print-this-url mentioned above does? --MattHodges

Google Suggest

Intrigued by the Firefox google bar completion, I hacked the following function for use with emacs-w3m:

    (defun google-suggest ()
     "Search `w3m-search-default-engine' with google completion canditates."
     (w3m-search w3m-search-default-engine
		 (completing-read  "Google search: "
   (defun google-suggest-aux (input)
	 (format "w3m -dump_source %s"
	(replace-regexp-in-string "," ""
				    (goto-char (point-min))
				    (re-search-forward "\(" (point-max) t 2)
				    (backward-char 1)
				     (1- (match-end 0)) (point)))))))


RichardRiley : doesn’t work for me :- completing-read: Symbol’s value as variable is void: google-suggest-aux

DamienProfeta : should work now with ‘ before google-suggest-aux

Easy forward/back in a new buffer

Are you ever in a position when you’re browsing a page in emacs-w3m and find yourself wishing you could keep looking at this page, but also open the previous (or next) page in history in the minimum number of keystrokes? Maybe not, but I definitely have.

Therefore, I wrote a couple of revised history navigation functions. They each work by calling the original, but if given an argument of at least 16 (C-u C-u) the page will open in a new buffer.

I find this most useful if bound to the respective keys currently bound to ‘w3m-view-previous-page’ and ‘w3m-view-next-page’. Anyway, here’s the code:

    (defun w3m-view-previous-page-2 (&optional count)
      "Move back count pages in the history.
    If `count' is a positive integer, move backward count times in the
    history.  If `count' is a negative integer, moving forward is performed.
    `count' is treated as 1 by default if it is omitted.
    If `count' is 16 (C-u C-u), it will open in a new buffer. If it is greater
    than 16, it will open in a new buffer and move backward `count' - 16 times."
      (interactive "p")
      (cond ((not count)
    	     (setq count 1))
    	    ((= count 16)
    	     (setq count 1)
    	    ((> count 16)
    	     (setq count (- count 16))
      (w3m-view-previous-page count))
    (defun w3m-view-next-page-2 (&optional count)
      "Move back count pages in the history.
    If `count' is a positive integer, move forward count times in the
    history.  If `count' is a negative integer, moving backwards is performed.
    `count' is treated as 1 by default if it is omitted.
    If `count' is 16 (C-u C-u), it will open in a new buffer. If it is greater
    than 16, it will open in a new buffer and move forward `count' - 16 times."
      (interactive "p")
      (cond ((not count)
    	     (setq count 1))
    	    ((= count 16)
    	     (setq count 1)
    	    ((> count 16)
    	     (setq count (- count 16))
       (w3m-view-next-page count))

– Amy

Disable default c-x b behaviour

 (add-hook 'w3m-mode-hook (lambda () (define-key w3m-mode-map (kbd "C-x b") nil)))

lynx-like multiple bookmark files

w3m-multibookmarks.el provides

  * multiple bookmarks files (default is to use the same as lynx)
  * A)dd D)ocument or L)ink keystrokes and url Title munging.

It is usable, even though it is in an early stage.

Currently, I’m mostly using it with emacs-w3m-1.4.4 and emacs-22.2 under slackware Linux.


– Rediscover

Access mobile versions of online services and web apps

The recent proliferation of handheld computing devices and the relatively lo-fi versions of popular online services provided for these can actually benefit users of relatively lo-fi, no-bells-no-whistles web-browsing software, such as emacs-w3m.

This is derived from my own experiments with the mobile versions of popular web-sites and online services.

It was all prompted by SachaChua’s discovery of how to access Facebook through Emacs, here:


As she says, make sure you set w3m-use-cookies to t.

Then, here goes:

 * Google Reader: access [[http://www.google.com/reader/m/view/]], and sign into
   your account as usual. Not nearly as cool as the full-blown version, but
   highly usable, this is my preferred method to read my RSS feeds right now.
 * Gmail: The basic HTML version of Gmail is actually quite usable from
   emacs-w3m. But you can also access the mobile device version of the service,
   here: [[http://mail.google.com/mail/x]], and, again, sign in as usual. The
   benefit of this approach is that this provides you with a stripped-down
   summary buffer of incoming mails.
   And, finally, Google Docs (yes, Google Docs):
 * Google Docs & Spreadsheets: Access the mobile interface to Google Docs here:
   [[http://docs.google.com/m]]. No, no editing for mobile devices here, obviously,
   but the interface provides you with a handy and searchable list
   of the documents in your account, which I find a very practical way to access
   my data directly from my Emacs buffers.

Erm, well, so much for AJAX and the singing-and-dancing, drag-and-drop web app interfaces…

If anyone else has had similar success with other online apps and services, this might be a good place to add up a nice list…


Use isearch for link following

The following code binds f to a variant of isearch which finds links only. RET will exit isearch and open the new site.

  (defvar w3m-isearch-links-do-wrap nil
    "Used internally for fast search wrapping.")
  (defun w3m-isearch-links (&optional regexp)
    (interactive "P")
    (let ((isearch-wrap-function
	   #'(lambda ()
	       (setq w3m-isearch-links-do-wrap nil)
	       (if isearch-forward
		   (goto-char (window-start))
		 (goto-char (window-end)))))
	   #'(lambda () 'w3m-isearch-links-search-fun))
	  post-command-hook		;inhibit link echoing
	   (list  #'(lambda nil
		      (when (and (not isearch-mode-end-hook-quit)
			(setq do-follow-link t))))))
      (setq w3m-isearch-links-do-wrap t)
      (isearch-mode t
		    ;; fast wrap
		    #'(lambda nil
			(if isearch-success
			    (setq w3m-isearch-links-do-wrap t)
			  (when w3m-isearch-links-do-wrap
			    (setq w3m-isearch-links-do-wrap nil)
			    (setq isearch-forward
				  (not isearch-forward))
			    (isearch-repeat isearch-forward))))
      (when do-follow-link
  (defun w3m-isearch-links-search-fun (string &optional bound no-error)
    (let* (isearch-search-fun-function
	   (search-fun  (isearch-search-fun))
	   (bound  (if isearch-forward
		       (max (or bound 0)
		     (min (or bound (window-start))
      (condition-case err
	  (while (and (apply search-fun (list string bound))
		      (not (w3m-anchor (point)))))
	(error (setq error err)))
      (if error
	  (if (not no-error)
	      (signal (car error) (cadr error)))
  (require 'w3m)
  (define-key w3m-mode-map [?f] 'w3m-isearch-links)


Removing trailing whitespace

Sometimes, it’s annoying when the w3m buffer has lots of trailing whitespaces. I do the following to remove trailing whitespace.

    (add-hook 'w3m-display-hook
              (lambda (url)
                (let ((buffer-read-only nil))


Consistent browse-url in buffers/w3m/gnus

Here I bind a key to rgr/browse-url and the code works out if its an encoded url beneath as in a w3m buffer. If you prefix your key with C-u it launches your system browser as opposed to the one you configured in w3m settings. e.g My default emacs w3m browser is w3m but if I hit C-u prioer to my browse key it launches Iceweasel in Debian. Very handy.

(defun rgr/browse (url)
  "If prefix is specified use the system default browser else use the configured emacs one"
  (if current-prefix-arg
      (when url (browse-url-default-browser url))
    (if  url (browse-url url) (call-interactively 'browse-url))

(defun rgr/browse-url (&optional url)
  "browse the url passed in"
  (setq url (or url (w3m-url-valid (w3m-anchor)) (browse-url-url-at-point) (region-or-word-at-point)))
  (setq url (read-string (format "Url \"%s\" :" url) url nil url))
  (rgr/browse url))


Import/merge bookmarks from Firefox

A Python script to transfer bookmarks exported from Firefox in the JSON format to the html format used by emacs-w3m, optionally merging them with an existing emacs-w3m bookmarks file (normally ~/.w3m/bookmark.html): http://jim.sdf-eu.org/etc/ffox2w3m.py . Written for my own purposes and not heavily tested, let me know if you have problems. JimBurton

Firefox can export his bookmarks to an html file, no need to use complex code to parse JSON. You can do that by using about:config or adding this to your user.js file:

// Export bookmarks form places.sqlite ==> bookmark.html
user_pref("browser.bookmarks.autoExportHTML", true);

When that done, you can see these bookmarks with bookmark-extensions.el (See BookmarkExtension) and/or you will find sources in Lisp:anything-config.el to show firefox bookmarks.


Conkeror/Vimperator functionality

If you like Conkeror/Vimperator style element selection/search, try w3m-lnum.el (part of emacs-w3m).

It enhances many point commands beyond current point. For example, if you’re not over link and invoke the enhanced version of w3m-print-this-url (w3m-lnum-this-url), you’ll be asked to select a link to be copied by entering number, where entering letters will filter currently visible links on their text part (<ctrl>+<number> will add <number> to the search string and <ctrl>+<space> adds space).

The swiss-army knives are w3m-lnum-universal and w3m-lnum-follow. w3m-lnum-universal: select whatever element and get a list of applicable actions over it. w3m-lnum-follow: depending on selected element may visit link, activate form field, toggle image or push a button. With prefix arguments its behaviour may be further controlled.

For full list of such commands try ‘L C-h’ within emacs-w3m buffer.

To customize some lnum options, just search for ‘w3m lnum’ within the Emacs customization interface.

You may replace original point commands with their enhanced versions (and also put w3m-lnum-universal at ‘w’, w3m-lnum-follow at ‘f’ as in Conkeror and w3m-linknum-goto at ‘F’ for quickly moving cursor to some link, image, form field or button) by activating the w3m-lnum-mode minor mode (‘M-x w3m-lnum-mode’ toggles it). You can automatically activate it by adding

(w3m-lnum-mode 1)

to your .emacs-w3m file or

(add-hook ‘w3m-mode-hook ‘w3m-lnum-mode)

before loading w3m.

For making arbitrary use of result of link numbering selection within Elisp, take a look at ‘w3m-lnum-get-action’. It takes a prompt and type of elements, does a selection and returns list of properties of the selection.

– Andrey Kotlarski

Middle click to open url in a new sesstion (tab)

I try to use:

    (define-key w3m-mode-map [mouse-2] 'w3m-mouse-view-this-url-new-session)

But it also changes the action of mouse-1. Ideas?

Copy html links to org-mode

You can copy a selection of text, including html links, from an emacs-w3m buffer into an org-mode buffer and have the html links automatically converted into org-mode links, so you don’t lose the url information.

Function ‘org-w3m-copy-for-org-mode’ is bound by default to “C-c C-x M-w” in emacs-w3m buffers for this purpose.


In addition to emacs-w3m native support for bookmarking, the following external extensions are available:

Bookmark to delicious

The following uses ‘curl’ and Lisp:anything-delicious.el (see ‘auth-source’ to configure).

        (defun w3m-add-delicious-bookmark (description tag)
          "Add a bookmark to delicious from w3m"
          (interactive (list (read-from-minibuffer "Description: "
                                                   nil nil nil nil
                             (completing-read "Tag: "
          (setq description
                (replace-regexp-in-string " " "+" description))
          (let* ((url     w3m-current-url)
                 (url-api (format anything-c-delicious-api-url-add
            (unless (and anything-delicious-user anything-delicious-password)
            (setq auth (concat anything-delicious-user ":" anything-delicious-password))
              (apply #'call-process "curl" nil t nil
              (goto-char (point-min))
              (if (re-search-forward "<result code=\"done\" />" nil t)
                         (message "%s added to delicious" description)
                         (when current-prefix-arg
                           (w3m-bookmark-write-file url
                                                    (replace-regexp-in-string "\+"
                                                                              " "
                           (message "%s added to delicious and to w3m-bookmarks" description)))
                  (message "Fail to add bookmark to delicious")
                  (when current-prefix-arg
                    (if (y-or-n-p "Add anyway to w3m-bookmarks?")
                          (w3m-bookmark-write-file url
                                                   (replace-regexp-in-string "\+" " "
                          (message "%s added to w3m-bookmarks" description))))))))

        (define-key w3m-mode-map "\C-x\C-a" 'w3m-add-delicious-bookmark)


Not as simple now that OAuth is used; compare http://delicious.com/help/api and http://delicious.com/help/oauthapi --jcorneli
Don’t know what is OAuth, i will have a look. However the actual above code of Lisp:anything-delicious.el work fine. I have updated it. – ThierryVolpiatto

Browse url on other window

add this into the configuraion file of the emacs, it would make the emacs work as help buffer. This would help if you use w3m to check document

(setq browse-url-browser-function 'w3m-browse-url-other-window)

(defun w3m-browse-url-other-window (url &optional newwin)
  (let ((w3m-pop-up-windows t))
    (if (one-window-p) (split-window))
    (other-window 1)
    (w3m-browse-url url newwin)))

DennyZhang: Please note, emacs23 has the functions of ffap-other-window/ffap-other-frame. If you always browse url in w3m, I think these functions are good enough.

However, I usually leverage external web browser, and sometimes I may use w3m for some simple web pages.

So my variable of browse-url-browser-function is not set as w3m way. Thus, I define below standalone function, for the case that we want to browse url in a seperate window of w3m mode.

(defun ffap-w3m-other-window (url &optional new-session)
  "Browse url in w3m.
  If current frame has only one window, create a new window and browse the webpage"
  (interactive (progn
                 (require 'browse-url)
                 (browse-url-interactive-arg "Emacs-w3m URL: ")))
  (let ((w3m-pop-up-windows t))
    (if (one-window-p) (split-window))
    (other-window 1)
    (w3m-browse-url url new-session)))

Improving w3m-browse-*

Some w3m-browse-* functions (e.g. w3m-browse-generic) rely on finding urls via browse-url-url-at-point, which in turn relies on (thing-at-point ‘url). However, thing-at-point does not seem to find urls for w3m’s links. That’s because a w3m link contains the url in the w3m-href-anchor text property. I use the following piece of advice to make sure that browse-url finds w3m’s own links.

;; make browse-url-url-at-point use w3m links if they exist
(defadvice browse-url-url-at-point (after w3m-anchor-at-point activate)
	"Browse the url at point. If w3m-anchor finds a url, use it."
	(setq ad-return-value 


Working with Gmail

To work with Gmail, w3m requires a one-line patch. After this, emacs-w3m works well with Gmail in Basic HTML mode. In particular, compared e.g. with mu4e, new mail is seen instantaneously, without needing to be fetched first by e.g. offlineimap.