2010-12-01

conkeror: web browsing the emacs way

Web browsing is one of the few computer-based activities for which I usually do not use emacs. Of course, there are of emacs-based browsers like w3m, which is pretty good. But for the 21st-century web, a text-mode browser is a bit limited. There are some efforts underway to integrate a graphical web browser experience in emacs (e.g., using Xembed), but it will take a while before that is ready.
The next best thing to web browsing with emacs, is a browser that is inspired by emacs. Such a browser exists: it's called conkeror (not to be confused with KDE's Konqueror). conkeror is a Mozilla-based browser that brings an emacs-like experience to web browsing. I've been using it for more than a year now as my primary browser, and I am quite happy with it.
Conkeror is a user-interface for the normal Mozilla/Firefox engine (xulrunner); this means that all those websites that work with Firefox, work just as well in conkeror, including things like ad-blockers, Java, Flash etc. and many plug-ins. This is a very important point for me.
If you like emacs, you'll probably also like conkeror. For starters, it uses many of the same key bindings – C-x C-f will open a url in a new buffer (tab), C-x 5 2 will open a new window (frame), I can inspect a key-binding with C-h k… and so on. Some of the single-key shortcuts are the same as those in w3m, like g to go to a webpage, or B to go back. Conkeror is fully keyboard-driven; it allows you do almost anything on the web without using the mouse – it can overlay numbers on items in a webpage so you can interact with them by their number. Of course, you can still use a mouse if you want, too.
The conkeror wiki gives many more examples. It also discusses installation in quite some detail, which makes life a bit easier for me :) Instead, I will just list a couple of the customizations I have made and encourage you to try for yourself.

configuration

Like emacs, conkeror is very configurable. The big difference is that conkeror uses Javascript instead of Elisp for the configuration; however, the concepts and naming should be familiar for emacs-users. Conkeror's equivalent of ~/.emacs is ~/.conkerorrc. Below are some snippets from my setup, that can hopefully help you to create your Perfect Browser ™; all examples below are based on the latest development version of Conkeror, as per end of November 2010.
First, some basics:
//allow for 'contrib' stuff
load_paths.unshift("chrome://conkeror-contrib/content/");

// teach me something whenever I start my browser
homepage = "http://en.wikipedia.org/wiki/Special:Random";

// give me new tabs; open buffers (tabs) in the background
require("new-tabs.js");
require("clicks-in-new-buffer.js");
clicks_in_new_buffer_target = OPEN_NEW_BUFFER_BACKGROUND; 
clicks_in_new_buffer_button = 1; //  midclick links in new buffers with

// auto completion in the minibuffer
minibuffer_auto_complete_default = true;
url_completion_use_history = true; // should work since bf05c87405
url_completion_use_bookmarks = true;

modeline customization

As in emacs, you can customize the modeline. Also in good emacs tradition, this is far from intuitive…
require("mode-line.js");
// funky icons in the modeline
require("mode-line-buttons.js");
mode_line_add_buttons(standard_mode_line_buttons, true);

// we'd like to see the # of buffers being loaded 
add_hook("mode_line_hook", mode_line_adder(loading_count_widget), true);
// we don't need a clock
remove_hook("mode_line_hook", mode_line_adder(clock_widget));

bookmarks

Plain-old bookmarks are easy to add with define_webjump – and you can just bind them to a short string. You can then 'jump' to the corresponding website by pressing g and then this short string. For example, to go to Emacs-Fu, you could type g efu RET. No mousing around needed.
// some bookmarks
define_webjump("conk",  "http://conkeror.org");
define_webjump("efu",   "http://emacs-fu.blogspot.com");
define_webjump("lkml",  "http://lkml.org");
define_webjump("ew",    "http://emacswiki.org");
// ...

smart links

Smartlinks are just like normal bookmarks, which the one difference that they contain an %s-parameter which will be replaced by whatever you type after the name of the bookmark. Thus, g imdb grande bouffe RET would take you to the IMDB-page about the movie La Grande Bouffe.
Some examples:
define_webjump("so",    "http://stackoverflow.com/search?q=%s");
define_webjump("yts",   "http://www.youtube.com/results?search_query=%s&aq=f");
define_webjump("imbd",  "http://www.imdb.com/find?s=all&q=%s");
// ...

integration with emacs

Another useful feature in conkeror is the ability to interact with Emacs (or any other text editor), so you can use emacs for writing text in web pages; for example, when you're using emacs-daemon (you should), you could can add the below, and C-i will then take you to emacs whenever you are in a text field in a web page.
editor_shell_command = "emacsclient -c";

adding your own functions

It's fairly easy to add your own functions; admittedly, I'm still at the beginning stages with that, but it's not too hard to combine the internal function, and assign them to key bindings. Some examples:
// copy url with C-c u
interactive("copy-url",
        "Copy the current buffer's URL to the clipboard",
        function(I) {
            var text = I.window.buffers.current.document.location.href;
            writeToClipboard(text);
            I.window.minibuffer.message("copied: " + text);
        }
);
define_key(default_global_keymap, "C-c u", "copy-url");


// reload conkerorrc with C-c r
interactive("reload-config", "reload conkerorrc",
       function(I) {
          load_rc();
          I.window.minibuffer.message("config reloaded");
       }
);
define_key(default_global_keymap, "C-c r", "reload-config");
It's not necessarily so easy to find the exact functions / objects you need to accomplish what you want. There's a certain learning curve – just like when using emacs.

integration with org-mode

The integration with emacs can go further than merely editing text fields though; it's possible to integrate conkeror with org-mode in emacs; I have the following in my .conkerorrc (this requires emacs-daemon), based on the code in WOrg:
// org-protocol stuff
function org_capture (url, title, selection, window) {
    var cmd_str =
        'emacsclient \"org-protocol:/capture:/w/'+url+'/'+title+'/'+selection+'\"';
    if (window != null) {
      window.minibuffer.message('Issuing ' + cmd_str);
    }
    shell_command_blind(cmd_str);
}

interactive("org-capture", "Clip url, title, and selection to capture via org-protocol",
          function (I) {
              org_capture(encodeURIComponent(I.buffer.display_uri_string),
                        encodeURIComponent(I.buffer.document.title),
                                encodeURIComponent(I.buffer.top_frame.getSelection()),
                        I.window);
          });
// capture with C-c c
define_key(content_buffer_normal_keymap, "C-c c", "org-capture");
Then, on the emacs-side (in your .emacs), you should have a capture template for this; for example:
;; ;; the 'w' corresponds with the 'w' used before as in:
;;   emacsclient \"org-protocol:/capture:/w/  [...]
(setq org-capture-templates
  '(
     ("w" "" entry ;; 'w' for 'org-protocol'
       (file+headline "www.org" "Notes")
       "* %^{Title}\n\n  Source: %u, %c\n\n  %i")
     ;; other templates
))
Now, when in conkeror, you can select some text, push C-c c ('capture'); emacs will offer you to save this text, including a link to the source, the date and so on, and saves it for later retrieval. I really love this feature!

so…

These were just a couple of the many things you can do with conkeror; there's so much potential here. I haven't discussed many of the other powerful features, such as the page-specific modes, that give special features to specific websites, be it GMail or Wikipedia.
I've been using this fine browser for a year or so now, and I really like it. There are a few rough edges here and there, but it's quite amazing what the small development team has accomplished. I heartily recommend it – for web-browsing the emacs-way, there's simple no better alternative.
Finally, if you're using conkeror already, and have some clever tricks you'd like to share, feel free to do so in the comments.

25 comments:

RBerenguel said...

Good to know, and just in time: Today I'm starting a 30 day challenge (see The Emacs 30 Day Challenge)of using "just emacs". Giving up all windows while I'm working (I used to have pidgin, chrome, bash and emacs with the occasional evince for PDF reading) and working from within emacs. Of course, there are several tasks where I can't do it, and general browsing is one of them (for quick things, w3m or lynx from within shell-mode will work fine, but 'general browsing'...), this somehow "solves" it. I'd love to see a similar back-end for Chrome, though. There is not even a decent set of keybindings, like firemacs for Firefox.

Cheers,

Ruben

Anonymous said...

For a Conkeror style link numbering on various elements within emacs-w3m, have a look at the recently updated trunk version of w3m-lnum.el.

verte said...

I would like to add one other thing I've discovered about conkeror: it is the cleanest code I've read in a long time.

Anonymous said...

just for the record it's "La Grande Bouffe" ;-)

djcb said...

@Anonymous: *ouch*. Thanks, fixed.

Anonymous said...

I'm definitely going to try this. I was thinking just the other day how much I wished that my web browser was more like Emacs! Does it feature an equivalent of ibuffer by any chance? That's pretty high on my want list.

oylenshpeegul said...

I just tried it for the first time myself. It seems that "C-x b" is already more like ibuffer than switch-to-buffer.

max said...

'm c 0' copies the current url or just 'm c' when there is just one frame.

'i c' copies the url of an image file.

elarson said...

You can also copy the URL of the page your are on via "c 0". Most of the commands that overlay numbers start at one, but zero ends up referencing the current page/url.

Great article! Conkeror is a fantastic browser!

Bill White said...

I suspect you've just changed my life for the better. Thanks!

Theomachos said...

Hm, Conkeror...nice !
Maybe you could try StumpWM next...

Oscar said...

I wanted a ibuffer-like thingy too, and found this: https://github.com/rafl/conkeror-ibuffer

I have *no* idea how to actually use it, though. Anyone?

be_slayed said...

Maybe of (related) interest: an emacs-like set of bindings for the Pentadactyl (< Vimperator) Firefox plugin which provide a similar keyboard-driven web-browsing experience.

Link here: http://babbagefiles.blogspot.com/2010/11/hack-emacs-like-bindings-for.html

Quick Ref Card here: http://www.jnanam.net/pentadactylemacs/pentadactylemacs.html

RBerenguel said...

I was about to post about c 0 and saw max and elarson comments. Been using conkeror for a week (since starting my emacs challenge) and I have been loving it.

Cheers,

Ruben

Anonymous said...

I really like the org-mode intergration. But it is not working for me. It just opens emac window and does not paste the selected text into the buffer. Am I missing anything?

djcb said...

@Anonymous: do you have emacs running, and is org-mode loaded? Maybe add

(require 'org-mode)
(require 'org-protocol)
(require 'org-capture)

to your .emacs?

OtherMichael said...

I had used Conkeror in the dim past, when it was a FireFox extension.

This post made me revisit it... and it's replacing a lot of other browsers...

Once sad thing, the annoying Flash-crash that used to crash FireFox, but now only crashes Flash? It completely crashes Conkeror. So it goes...

dickoa said...

Hi...i try to use emacs whenever i can, and it's a very useful post. But i'm not yet an emacs expert, and the learning curve is steep.
I want to know, how to use okular (i use kubuntu 10.4) for pdf viewing inside buffer (or outside), cause now it's impossible for me
Thank you for your fantastic blog (and sorry for my poor english)

djcb said...

@dickoa: in my .conkerorrc, I have

external_content_handlers.set("application/pdf", "evince");

I suspect replacing 'evince' with 'okular' should work.

be_slayed said...

Ok, I've become a Conkeror convert. I was using the Pentadactyl extension since that allowed me to use other Firefox extensions...but Conkeror is much better over-all. My web-browsing has been significantly streamlined.

dickoa said...

Yes it's work like a charm...thank's

be_slayed said...

Here are some more useful configs and tips for conkeror: http://babbagefiles.blogspot.com/2011/01/conkeror-browsing-web-emacs-style.html

Eli Taz said...

I'm rather liking it, though yes, the learning curve is pretty steep. I'm not totally convinced to abandon Firefox for Conkeror, but at least it's nice to have an alternate that I can play with.

Unfortunately I can't figure out how to change the background colour of the mode line.

Anonymous said...

Hi,
thx a lot, all the posts are so usefull !
I'd like just to show how it's easy to install adblock plus, since
it's a sine-qua-non condition for me to use a browser.
As always the information is in [[http://www.conkeror.org/Extensions][the documentation]].
Just write this in you ~/.conkerorrc to allow the installation :
#+BEGIN_SRC c
session_pref("xpinstall.whitelist.required", false);
#+END_SRC
restart conkeror
and install adblock :
http://adblockplus.org/en/
and subscribe to a filter with M-x extensions.

this comment was written in emacs launched from conkeror
with some org-mode and yasnippet but maybe I shouldn't have done so ... :p

Anonymous said...

KeySnail for Firefox is much better.

https://github.com/mooz/keysnail/wiki/